From 1c473ba84307201b0d072da68a17aee8c913efa8 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sat, 1 May 2004 14:41:21 +0000 Subject: (gl_PREREQ_CHOWN): Check for fcntl.h. See if we need an fchown replacement. (gl_FUNC_CHOWN_FOLLOWS_SYMLINK): New macro. (gl_FUNC_CHOWN): Require gl_FUNC_CHOWN_FOLLOWS_SYMLINK, and use the replacement function if we detect either defect. --- m4/chown.m4 | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 9 deletions(-) (limited to 'm4') diff --git a/m4/chown.m4 b/m4/chown.m4 index f723cb576..430bc8073 100644 --- a/m4/chown.m4 +++ b/m4/chown.m4 @@ -1,15 +1,24 @@ -#serial 9 - -dnl From Jim Meyering. -dnl Determine whether chown accepts arguments of -1 for uid and gid. -dnl If it doesn't, arrange to use the replacement function. -dnl +#serial 10 +# Determine whether we need the chown wrapper. chown should accept +# arguments of -1 for uid and gid, and it should dereference symlinks. +# If it doesn't, arrange to use the replacement function. +# From Jim Meyering. AC_DEFUN([gl_FUNC_CHOWN], [ - AC_REQUIRE([AC_TYPE_UID_T])dnl + AC_REQUIRE([AC_TYPE_UID_T]) AC_REQUIRE([AC_FUNC_CHOWN]) - if test $ac_cv_func_chown_works = no; then + AC_REQUIRE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK]) + + if test $ac_cv_func_chown_works = yes; then + AC_DEFINE(CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE, 1, + [Define if chown is not POSIX compliant regarding IDs of -1.]) + fi + + # If chown has either of the above problems, then we need the wrapper. + if test $ac_cv_func_chown_works$gl_cv_func_chown_follows_symlink = yesyes; then + : # no wrapper needed + else AC_LIBOBJ(chown) AC_DEFINE(chown, rpl_chown, [Define to rpl_chown if the replacement function should be used.]) @@ -17,8 +26,51 @@ AC_DEFUN([gl_FUNC_CHOWN], fi ]) +# Determine whether chown follows symlinks (it should). +AC_DEFUN([gl_FUNC_CHOWN_FOLLOWS_SYMLINK], +[ + AC_CACHE_CHECK( + [whether chown(2) dereferences symlinks], + gl_cv_func_chown_follows_symlink, + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include + + int + main () + { + char const *dangling_symlink = "conftest.dangle"; + + unlink (dangling_symlink); + if (symlink ("conftest.no-such", dangling_symlink)) + abort (); + + /* Exit successfully on a conforming system, + i.e., where chown must fail with ENOENT. */ + exit ( ! (chown (dangling_symlink, getuid (), getgid ()) != 0 + && errno == ENOENT)); + } + ]])], + [gl_cv_func_chown_follows_symlink=yes], + [gl_cv_func_chown_follows_symlink=no], + [gl_cv_func_chown_follows_symlink=no] + ) + ] + ) + + if test $gl_cv_func_chown_follows_symlink = no; then + AC_DEFINE(CHOWN_MODIFIES_SYMLINK, 1, + [Define if chown modifies symlinks.]) + fi +]) + # Prerequisites of lib/chown.c. AC_DEFUN([gl_PREREQ_CHOWN], [ - AC_CHECK_HEADERS_ONCE(unistd.h) + AC_CHECK_HEADERS_ONCE(unistd.h fcntl.h) + AC_CHECK_FUNC([fchown], , [AC_LIBOBJ(fchown-stub)]) ]) -- cgit v1.2.3-70-g09d2