From 64c2e4a530837b13f987f5de386c49bac90aef43 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 29 May 2021 12:10:38 -0400 Subject: [PATCH] gnulib: import chown A few sims use this to emulate chown syscalls. --- gnulib/ChangeLog | 8 + gnulib/Makefile.in | 1 + gnulib/aclocal.m4 | 1 + gnulib/config.in | 22 ++ gnulib/configure | 482 ++++++++++++++++++++++++++----- gnulib/import/Makefile.am | 10 + gnulib/import/Makefile.in | 31 +- gnulib/import/chown.c | 151 ++++++++++ gnulib/import/fchown-stub.c | 34 +++ gnulib/import/m4/chown.m4 | 218 ++++++++++++++ gnulib/import/m4/gnulib-cache.m4 | 2 + gnulib/import/m4/gnulib-comp.m4 | 12 + gnulib/update-gnulib.sh | 1 + 13 files changed, 892 insertions(+), 81 deletions(-) create mode 100644 gnulib/import/chown.c create mode 100644 gnulib/import/fchown-stub.c create mode 100644 gnulib/import/m4/chown.m4 diff --git a/gnulib/ChangeLog b/gnulib/ChangeLog index 1563e04119b..f5a0a32cb4f 100644 --- a/gnulib/ChangeLog +++ b/gnulib/ChangeLog @@ -1,3 +1,11 @@ +2021-06-08 Mike Frysinger + + * update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add chown. + * aclocal.m4, config.in, configure, Makefile.in, import/Makefile.am, + import/Makefile.in, import/m4/gnulib-cache.m4, + import/m4/gnulib-comp.m4: Regenerate. + * import/chown.c, import/fchown-stub.c, import/m4/chown.m4: New files. + 2021-05-24 Mike Frysinger * update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add ffs. diff --git a/gnulib/Makefile.in b/gnulib/Makefile.in index 4c46e0a99e7..04dc454701e 100644 --- a/gnulib/Makefile.in +++ b/gnulib/Makefile.in @@ -121,6 +121,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/import/m4/builtin-expect.m4 \ $(top_srcdir)/import/m4/canonicalize.m4 \ $(top_srcdir)/import/m4/chdir-long.m4 \ + $(top_srcdir)/import/m4/chown.m4 \ $(top_srcdir)/import/m4/clock_time.m4 \ $(top_srcdir)/import/m4/close.m4 \ $(top_srcdir)/import/m4/closedir.m4 \ diff --git a/gnulib/aclocal.m4 b/gnulib/aclocal.m4 index 00a0c9c0d95..d466a2666ca 100644 --- a/gnulib/aclocal.m4 +++ b/gnulib/aclocal.m4 @@ -1193,6 +1193,7 @@ m4_include([import/m4/btowc.m4]) m4_include([import/m4/builtin-expect.m4]) m4_include([import/m4/canonicalize.m4]) m4_include([import/m4/chdir-long.m4]) +m4_include([import/m4/chown.m4]) m4_include([import/m4/clock_time.m4]) m4_include([import/m4/close.m4]) m4_include([import/m4/closedir.m4]) diff --git a/gnulib/config.in b/gnulib/config.in index e3f581423f9..15abb17cb44 100644 --- a/gnulib/config.in +++ b/gnulib/config.in @@ -18,6 +18,19 @@ /* Define to the number of bits in type 'wint_t'. */ #undef BITSIZEOF_WINT_T +/* Define to 1 if chown fails to change ctime when at least one argument was + not -1. */ +#undef CHOWN_CHANGE_TIME_BUG + +/* Define if chown is not POSIX compliant regarding IDs of -1. */ +#undef CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE + +/* Define if chown modifies symlinks. */ +#undef CHOWN_MODIFIES_SYMLINK + +/* Define to 1 if chown mishandles trailing slash. */ +#undef CHOWN_TRAILING_SLASH_BUG + /* Define to 1 if using 'alloca.c'. */ #undef C_ALLOCA @@ -140,6 +153,9 @@ /* Define to 1 when the gnulib module chdir should be tested. */ #undef GNULIB_TEST_CHDIR +/* Define to 1 when the gnulib module chown should be tested. */ +#undef GNULIB_TEST_CHOWN + /* Define to 1 when the gnulib module cloexec should be tested. */ #undef GNULIB_TEST_CLOEXEC @@ -355,6 +371,9 @@ /* Define to 1 if you have the `catgets' function. */ #undef HAVE_CATGETS +/* Define to 1 if you have the `chown' function. */ +#undef HAVE_CHOWN + /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME @@ -521,6 +540,9 @@ /* Define to 1 if you have the `fchdir' function. */ #undef HAVE_FCHDIR +/* Define to 1 if you have the `fchown' function. */ +#undef HAVE_FCHOWN + /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL diff --git a/gnulib/configure b/gnulib/configure index 2ddb1d7cbb0..827393a6d25 100644 --- a/gnulib/configure +++ b/gnulib/configure @@ -3725,6 +3725,8 @@ as_fn_append ac_func_list " faccessat" as_fn_append ac_func_list " realpath" as_fn_append ac_header_list " sys/param.h" as_fn_append ac_header_list " unistd.h" +as_fn_append ac_func_list " chown" +as_fn_append ac_func_list " fchown" as_fn_append ac_func_list " _set_invalid_parameter_handler" as_fn_append ac_func_list " fchdir" as_fn_append ac_header_list " dirent.h" @@ -6685,6 +6687,7 @@ fi # Code from module canonicalize-lgpl: # Code from module chdir: # Code from module chdir-long: + # Code from module chown: # Code from module clock-time: # Code from module cloexec: # Code from module close: @@ -8281,50 +8284,35 @@ done +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then +$as_echo "#define uid_t int" >>confdefs.h - if test $ac_cv_func__set_invalid_parameter_handler = yes; then - HAVE_MSVC_INVALID_PARAMETER_HANDLER=1 - -$as_echo "#define HAVE_MSVC_INVALID_PARAMETER_HANDLER 1" >>confdefs.h - - else - HAVE_MSVC_INVALID_PARAMETER_HANDLER=0 - fi - - - - - - GNULIB_OPENDIR=0; - GNULIB_READDIR=0; - GNULIB_REWINDDIR=0; - GNULIB_CLOSEDIR=0; - GNULIB_DIRFD=0; - GNULIB_FDOPENDIR=0; - GNULIB_SCANDIR=0; - GNULIB_ALPHASORT=0; - HAVE_OPENDIR=1; - HAVE_READDIR=1; - HAVE_REWINDDIR=1; - HAVE_CLOSEDIR=1; - HAVE_DECL_DIRFD=1; - HAVE_DECL_FDOPENDIR=1; - HAVE_FDOPENDIR=1; - HAVE_SCANDIR=1; - HAVE_ALPHASORT=1; - REPLACE_OPENDIR=0; - REPLACE_CLOSEDIR=0; - REPLACE_DIRFD=0; - REPLACE_FDOPENDIR=0; - - - GNULIB_ISBLANK=0; - HAVE_ISBLANK=1; +$as_echo "#define gid_t int" >>confdefs.h +fi gl_mda_defines=' #if defined _WIN32 && !defined __CYGWIN__ @@ -8382,6 +8370,354 @@ gl_mda_defines=' ' + for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working chown" >&5 +$as_echo_n "checking for working chown... " >&6; } +if ${ac_cv_func_chown_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + case "$host_os" in # (( + # Guess yes on Linux systems. + linux-* | linux) ac_cv_func_chown_works="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) ac_cv_func_chown_works="guessing yes" ;; + # Guess no on native Windows. + mingw*) ac_cv_func_chown_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) ac_cv_func_chown_works="$gl_cross_guess_normal" ;; + esac + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + #include + + +$gl_mda_defines + +int +main () +{ + + char *f = "conftest.chown"; + struct stat before, after; + + if (creat (f, 0600) < 0) + return 1; + if (stat (f, &before) < 0) + return 1; + if (chown (f, (uid_t) -1, (gid_t) -1) == -1) + return 1; + if (stat (f, &after) < 0) + return 1; + return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid); + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_chown_works=yes +else + ac_cv_func_chown_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + rm -f conftest.chown + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chown_works" >&5 +$as_echo "$ac_cv_func_chown_works" >&6; } + case "$ac_cv_func_chown_works" in + *yes) + +$as_echo "#define HAVE_CHOWN 1" >>confdefs.h + + ;; + esac + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether chown dereferences symlinks" >&5 +$as_echo_n "checking whether chown dereferences symlinks... " >&6; } +if ${gl_cv_func_chown_follows_symlink+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + gl_cv_func_chown_follows_symlink="guessing yes" + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + + +$gl_mda_defines + + int + main () + { + int result = 0; + 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. */ + if (chown (dangling_symlink, getuid (), getgid ()) == 0) + result |= 1; + if (errno != ENOENT) + result |= 2; + return result; + } + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_chown_follows_symlink=yes +else + gl_cv_func_chown_follows_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_chown_follows_symlink" >&5 +$as_echo "$gl_cv_func_chown_follows_symlink" >&6; } + + case "$gl_cv_func_chown_follows_symlink" in + *yes) ;; + *) + +$as_echo "#define CHOWN_MODIFIES_SYMLINK 1" >>confdefs.h + + ;; + esac + + + + + + + + + + + + + if test $ac_cv_func_chown = no; then + HAVE_CHOWN=0 + else + case "$gl_cv_func_chown_follows_symlink" in + *yes) ;; + *) REPLACE_CHOWN=1 ;; + esac + + case "$ac_cv_func_chown_works" in + *no) + +$as_echo "#define CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE 1" >>confdefs.h + + REPLACE_CHOWN=1 + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether chown honors trailing slash" >&5 +$as_echo_n "checking whether chown honors trailing slash... " >&6; } +if ${gl_cv_func_chown_slash_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + touch conftest.file && rm -f conftest.link + if test "$cross_compiling" = yes; then : + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_chown_slash_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_chown_slash_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_chown_slash_works="$gl_cross_guess_normal" ;; + esac + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + + +$gl_mda_defines + +int +main () +{ +if (symlink ("conftest.file", "conftest.link")) return 1; + if (chown ("conftest.link/", getuid (), getgid ()) == 0) return 2; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_chown_slash_works=yes +else + gl_cv_func_chown_slash_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + rm -f conftest.link conftest.file +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_chown_slash_works" >&5 +$as_echo "$gl_cv_func_chown_slash_works" >&6; } + case "$gl_cv_func_chown_slash_works" in + *yes) ;; + *) + +$as_echo "#define CHOWN_TRAILING_SLASH_BUG 1" >>confdefs.h + + REPLACE_CHOWN=1 + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether chown always updates ctime" >&5 +$as_echo_n "checking whether chown always updates ctime... " >&6; } +if ${gl_cv_func_chown_ctime_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_chown_ctime_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_chown_ctime_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_chown_ctime_works="$gl_cross_guess_normal" ;; + esac + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + + +$gl_mda_defines + +int +main () +{ +struct stat st1, st2; + if (close (creat ("conftest.file", 0600))) return 1; + if (stat ("conftest.file", &st1)) return 2; + sleep (1); + if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3; + if (stat ("conftest.file", &st2)) return 4; + if (st2.st_ctime <= st1.st_ctime) return 5; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_chown_ctime_works=yes +else + gl_cv_func_chown_ctime_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + rm -f conftest.file +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_chown_ctime_works" >&5 +$as_echo "$gl_cv_func_chown_ctime_works" >&6; } + case "$gl_cv_func_chown_ctime_works" in + *yes) ;; + *) + +$as_echo "#define CHOWN_CHANGE_TIME_BUG 1" >>confdefs.h + + REPLACE_CHOWN=1 + ;; + esac + fi + + + + + + if test $ac_cv_func__set_invalid_parameter_handler = yes; then + HAVE_MSVC_INVALID_PARAMETER_HANDLER=1 + +$as_echo "#define HAVE_MSVC_INVALID_PARAMETER_HANDLER 1" >>confdefs.h + + else + HAVE_MSVC_INVALID_PARAMETER_HANDLER=0 + fi + + + + + + GNULIB_OPENDIR=0; + GNULIB_READDIR=0; + GNULIB_REWINDDIR=0; + GNULIB_CLOSEDIR=0; + GNULIB_DIRFD=0; + GNULIB_FDOPENDIR=0; + GNULIB_SCANDIR=0; + GNULIB_ALPHASORT=0; + HAVE_OPENDIR=1; + HAVE_READDIR=1; + HAVE_REWINDDIR=1; + HAVE_CLOSEDIR=1; + HAVE_DECL_DIRFD=1; + HAVE_DECL_FDOPENDIR=1; + HAVE_FDOPENDIR=1; + HAVE_SCANDIR=1; + HAVE_ALPHASORT=1; + REPLACE_OPENDIR=0; + REPLACE_CLOSEDIR=0; + REPLACE_DIRFD=0; + REPLACE_FDOPENDIR=0; + + + GNULIB_ISBLANK=0; + HAVE_ISBLANK=1; + + + + @@ -16208,36 +16544,6 @@ fi HAVE_SIGSET_T=0 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 -$as_echo_n "checking for uid_t in sys/types.h... " >&6; } -if ${ac_cv_type_uid_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1; then : - ac_cv_type_uid_t=yes -else - ac_cv_type_uid_t=no -fi -rm -f conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 -$as_echo "$ac_cv_type_uid_t" >&6; } -if test $ac_cv_type_uid_t = no; then - -$as_echo "#define uid_t int" >>confdefs.h - - -$as_echo "#define gid_t int" >>confdefs.h - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : @@ -17891,6 +18197,46 @@ $as_echo "$gl_cv_have_unlimited_file_name_length" >&6; } : fi + if test $HAVE_CHOWN = 0 || test $REPLACE_CHOWN = 1; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS chown.$ac_objext" + + fi + if test $REPLACE_CHOWN = 1 && test $ac_cv_func_fchown = no; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS fchown-stub.$ac_objext" + + fi + + + + + + GNULIB_CHOWN=1 + + + + + +$as_echo "#define GNULIB_TEST_CHOWN 1" >>confdefs.h + + + + # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. diff --git a/gnulib/import/Makefile.am b/gnulib/import/Makefile.am index e99adab7a22..30b8afd2846 100644 --- a/gnulib/import/Makefile.am +++ b/gnulib/import/Makefile.am @@ -35,6 +35,7 @@ # --no-vc-files \ # alloca \ # canonicalize-lgpl \ +# chown \ # count-one-bits \ # dirent \ # dirfd \ @@ -237,6 +238,15 @@ EXTRA_libgnu_a_SOURCES += chdir-long.c ## end gnulib module chdir-long +## begin gnulib module chown + + +EXTRA_DIST += chown.c fchown-stub.c + +EXTRA_libgnu_a_SOURCES += chown.c fchown-stub.c + +## end gnulib module chown + ## begin gnulib module cloexec libgnu_a_SOURCES += cloexec.c diff --git a/gnulib/import/Makefile.in b/gnulib/import/Makefile.in index e02adc633ea..d8a31f83de4 100644 --- a/gnulib/import/Makefile.in +++ b/gnulib/import/Makefile.in @@ -49,6 +49,7 @@ # --no-vc-files \ # alloca \ # canonicalize-lgpl \ +# chown \ # count-one-bits \ # dirent \ # dirfd \ @@ -182,6 +183,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/import/m4/builtin-expect.m4 \ $(top_srcdir)/import/m4/canonicalize.m4 \ $(top_srcdir)/import/m4/chdir-long.m4 \ + $(top_srcdir)/import/m4/chown.m4 \ $(top_srcdir)/import/m4/clock_time.m4 \ $(top_srcdir)/import/m4/close.m4 \ $(top_srcdir)/import/m4/closedir.m4 \ @@ -1787,12 +1789,12 @@ noinst_LTLIBRARIES = # No GNU Make output. EXTRA_DIST = m4/gnulib-cache.m4 alloca.c alloca.in.h arpa_inet.in.h \ assure.h attribute.h basename-lgpl.h btowc.c \ - canonicalize-lgpl.c chdir-long.c chdir-long.h cloexec.h \ - close.c closedir.c dirent-private.h count-one-bits.h \ - ctype.in.h dirent.in.h dirfd.c dirname.h dup.c dup2.c \ - eloop-threshold.h errno.in.h error.c error.h exitfail.h \ - fchdir.c fcntl.c fcntl.in.h fd-hook.h fdopendir.c ffs.c \ - filename.h filenamecat.h flexmember.h float.c float.in.h \ + canonicalize-lgpl.c chdir-long.c chdir-long.h chown.c \ + fchown-stub.c cloexec.h close.c closedir.c dirent-private.h \ + count-one-bits.h ctype.in.h dirent.in.h dirfd.c dirname.h \ + dup.c dup2.c eloop-threshold.h errno.in.h error.c error.h \ + exitfail.h fchdir.c fcntl.c fcntl.in.h fd-hook.h fdopendir.c \ + ffs.c filename.h filenamecat.h flexmember.h float.c float.in.h \ itold.c fnmatch.c fnmatch_loop.c fnmatch.c fnmatch.in.h \ fpucw.h free.c frexp.c frexp.c frexpl.c fstat.c stat-w32.c \ stat-w32.h at-func.c fstatat.c \ @@ -1876,13 +1878,14 @@ libgnu_a_SOURCES = openat-priv.h openat-proc.c basename-lgpl.c \ libgnu_a_LIBADD = $(gl_LIBOBJS) @ALLOCA@ libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@ EXTRA_libgnu_a_SOURCES = alloca.c btowc.c canonicalize-lgpl.c \ - chdir-long.c close.c closedir.c dirfd.c dup.c dup2.c error.c \ - fchdir.c fcntl.c fdopendir.c ffs.c float.c itold.c fnmatch.c \ - fnmatch_loop.c fnmatch.c free.c frexp.c frexp.c frexpl.c \ - fstat.c stat-w32.c at-func.c fstatat.c getcwd.c getcwd-lgpl.c \ - getdelim.c getdtablesize.c getline.c getlogin_r.c getrandom.c \ - gettimeofday.c glob.c glob_pattern_p.c globfree.c inet_ntop.c \ - isblank.c isnan.c isnand.c isnan.c isnanl.c lstat.c malloc.c \ + chdir-long.c chown.c fchown-stub.c close.c closedir.c dirfd.c \ + dup.c dup2.c error.c fchdir.c fcntl.c fdopendir.c ffs.c \ + float.c itold.c fnmatch.c fnmatch_loop.c fnmatch.c free.c \ + frexp.c frexp.c frexpl.c fstat.c stat-w32.c at-func.c \ + fstatat.c getcwd.c getcwd-lgpl.c getdelim.c getdtablesize.c \ + getline.c getlogin_r.c getrandom.c gettimeofday.c glob.c \ + glob_pattern_p.c globfree.c inet_ntop.c isblank.c isnan.c \ + isnand.c isnan.c isnanl.c lstat.c malloc.c \ lc-charset-dispatch.c mbrtowc.c mbtowc-lock.c mbsinit.c \ mbsrtowcs-state.c mbsrtowcs.c mbtowc.c memchr.c memmem.c \ memmem.c mempcpy.c memrchr.c mkdir.c mkdtemp.c mkostemp.c \ @@ -2010,6 +2013,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btowc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonicalize-lgpl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chdir-long.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chown.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloexec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closedir.Po@am__quote@ @@ -2023,6 +2027,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exitfail.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchown-stub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcntl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd-hook.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd-safer-flag.Po@am__quote@ diff --git a/gnulib/import/chown.c b/gnulib/import/chown.c new file mode 100644 index 00000000000..9b8b36192c9 --- /dev/null +++ b/gnulib/import/chown.c @@ -0,0 +1,151 @@ +/* provide consistent interface to chown for systems that don't interpret + an ID of -1 as meaning "don't change the corresponding ID". + + Copyright (C) 1997, 2004-2007, 2009-2021 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* written by Jim Meyering */ + +#include + +/* Specification. */ +#include + +#include +#include +#include +#include +#include + +#if !HAVE_CHOWN + +/* Simple stub that always fails with ENOSYS, for mingw. */ +int +chown (const char *file _GL_UNUSED, uid_t uid _GL_UNUSED, + gid_t gid _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_CHOWN */ + +/* Below we refer to the system's chown(). */ +# undef chown + +/* Provide a more-closely POSIX-conforming version of chown on + systems with one or both of the following problems: + - chown doesn't treat an ID of -1 as meaning + "don't change the corresponding ID". + - chown doesn't dereference symlinks. */ + +int +rpl_chown (const char *file, uid_t uid, gid_t gid) +{ + struct stat st; + bool stat_valid = false; + int result; + +# if CHOWN_CHANGE_TIME_BUG + if (gid != (gid_t) -1 || uid != (uid_t) -1) + { + if (stat (file, &st)) + return -1; + stat_valid = true; + } +# endif + +# if CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE + if (gid == (gid_t) -1 || uid == (uid_t) -1) + { + /* Stat file to get id(s) that should remain unchanged. */ + if (!stat_valid && stat (file, &st)) + return -1; + if (gid == (gid_t) -1) + gid = st.st_gid; + if (uid == (uid_t) -1) + uid = st.st_uid; + } +# endif + +# if CHOWN_MODIFIES_SYMLINK + { + /* Handle the case in which the system-supplied chown function + does *not* follow symlinks. Instead, it changes permissions + on the symlink itself. To work around that, we open the + file (but this can fail due to lack of read or write permission) and + use fchown on the resulting descriptor. */ + int open_flags = O_NONBLOCK | O_NOCTTY | O_CLOEXEC; + int fd = open (file, O_RDONLY | open_flags); + if (0 <= fd + || (errno == EACCES + && 0 <= (fd = open (file, O_WRONLY | open_flags)))) + { + int saved_errno; + bool fchown_socket_failure; + + result = fchown (fd, uid, gid); + saved_errno = errno; + + /* POSIX says fchown can fail with errno == EINVAL on sockets + and pipes, so fall back on chown in that case. */ + fchown_socket_failure = + (result != 0 && saved_errno == EINVAL + && fstat (fd, &st) == 0 + && (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode))); + + close (fd); + + if (! fchown_socket_failure) + { + errno = saved_errno; + return result; + } + } + else if (errno != EACCES) + return -1; + } +# endif + +# if CHOWN_TRAILING_SLASH_BUG + if (!stat_valid) + { + size_t len = strlen (file); + if (len && file[len - 1] == '/' && stat (file, &st)) + return -1; + } +# endif + + result = chown (file, uid, gid); + +# if CHOWN_CHANGE_TIME_BUG + if (result == 0 && stat_valid + && (uid == st.st_uid || uid == (uid_t) -1) + && (gid == st.st_gid || gid == (gid_t) -1)) + { + /* No change in ownership, but at least one argument was not -1, + so we are required to update ctime. Since chown succeeded, + we assume that chmod will do likewise. Fortunately, on all + known systems where a 'no-op' chown skips the ctime update, a + 'no-op' chmod still does the trick. */ + result = chmod (file, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO + | S_ISUID | S_ISGID | S_ISVTX)); + } +# endif + + return result; +} + +#endif /* HAVE_CHOWN */ diff --git a/gnulib/import/fchown-stub.c b/gnulib/import/fchown-stub.c new file mode 100644 index 00000000000..f549ff300a4 --- /dev/null +++ b/gnulib/import/fchown-stub.c @@ -0,0 +1,34 @@ +/* Change ownership of a file. + Copyright (C) 2004-2021 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert, 2004. */ + +#include + +#include +#include + +/* A trivial substitute for 'fchown'. + + DJGPP 2.03 and earlier (and perhaps later) don't have 'fchown', + so we pretend no-one has permission for this operation. */ + +int +fchown (int fd, uid_t uid, gid_t gid) +{ + errno = EPERM; + return -1; +} diff --git a/gnulib/import/m4/chown.m4 b/gnulib/import/m4/chown.m4 new file mode 100644 index 00000000000..d1c083175e6 --- /dev/null +++ b/gnulib/import/m4/chown.m4 @@ -0,0 +1,218 @@ +# serial 35 +# Determine whether we need the chown wrapper. + +dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2021 Free Software +dnl Foundation, Inc. + +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# 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. + +# This is taken from the following Autoconf patch: +# https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 +AC_DEFUN([AC_FUNC_CHOWN], +[ + AC_REQUIRE([AC_TYPE_UID_T])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles + AC_CHECK_HEADERS([unistd.h]) + AC_CACHE_CHECK([for working chown], + [ac_cv_func_chown_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT + [#include + ]GL_MDA_DEFINES], + [[ + char *f = "conftest.chown"; + struct stat before, after; + + if (creat (f, 0600) < 0) + return 1; + if (stat (f, &before) < 0) + return 1; + if (chown (f, (uid_t) -1, (gid_t) -1) == -1) + return 1; + if (stat (f, &after) < 0) + return 1; + return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid); + ]]) + ], + [ac_cv_func_chown_works=yes], + [ac_cv_func_chown_works=no], + [case "$host_os" in # (( + # Guess yes on Linux systems. + linux-* | linux) ac_cv_func_chown_works="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) ac_cv_func_chown_works="guessing yes" ;; + # Guess no on native Windows. + mingw*) ac_cv_func_chown_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) ac_cv_func_chown_works="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.chown + ]) + case "$ac_cv_func_chown_works" in + *yes) + AC_DEFINE([HAVE_CHOWN], [1], + [Define to 1 if your system has a working `chown' function.]) + ;; + esac +])# AC_FUNC_CHOWN + +AC_DEFUN_ONCE([gl_FUNC_CHOWN], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_TYPE_UID_T]) + AC_REQUIRE([AC_FUNC_CHOWN]) + AC_REQUIRE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CHECK_FUNCS_ONCE([chown fchown]) + + dnl mingw lacks chown altogether. + if test $ac_cv_func_chown = no; then + HAVE_CHOWN=0 + else + dnl Some old systems treated chown like lchown. + case "$gl_cv_func_chown_follows_symlink" in + *yes) ;; + *) REPLACE_CHOWN=1 ;; + esac + + dnl Some old systems tried to use uid/gid -1 literally. + case "$ac_cv_func_chown_works" in + *no) + AC_DEFINE([CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE], [1], + [Define if chown is not POSIX compliant regarding IDs of -1.]) + REPLACE_CHOWN=1 + ;; + esac + + dnl Solaris 9 ignores trailing slash. + dnl FreeBSD 7.2 mishandles trailing slash on symlinks. + dnl Likewise for AIX 7.1. + AC_CACHE_CHECK([whether chown honors trailing slash], + [gl_cv_func_chown_slash_works], + [touch conftest.file && rm -f conftest.link + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +]GL_MDA_DEFINES], + [[if (symlink ("conftest.file", "conftest.link")) return 1; + if (chown ("conftest.link/", getuid (), getgid ()) == 0) return 2; + ]])], + [gl_cv_func_chown_slash_works=yes], + [gl_cv_func_chown_slash_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_chown_slash_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_chown_slash_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_chown_slash_works="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.link conftest.file]) + case "$gl_cv_func_chown_slash_works" in + *yes) ;; + *) + AC_DEFINE([CHOWN_TRAILING_SLASH_BUG], [1], + [Define to 1 if chown mishandles trailing slash.]) + REPLACE_CHOWN=1 + ;; + esac + + dnl OpenBSD fails to update ctime if ownership does not change. + AC_CACHE_CHECK([whether chown always updates ctime], + [gl_cv_func_chown_ctime_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +]GL_MDA_DEFINES], + [[struct stat st1, st2; + if (close (creat ("conftest.file", 0600))) return 1; + if (stat ("conftest.file", &st1)) return 2; + sleep (1); + if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3; + if (stat ("conftest.file", &st2)) return 4; + if (st2.st_ctime <= st1.st_ctime) return 5; + ]])], + [gl_cv_func_chown_ctime_works=yes], + [gl_cv_func_chown_ctime_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_chown_ctime_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_chown_ctime_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_chown_ctime_works="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.file]) + case "$gl_cv_func_chown_ctime_works" in + *yes) ;; + *) + AC_DEFINE([CHOWN_CHANGE_TIME_BUG], [1], [Define to 1 if chown fails + to change ctime when at least one argument was not -1.]) + REPLACE_CHOWN=1 + ;; + esac + fi +]) + +# Determine whether chown follows symlinks (it should). +AC_DEFUN_ONCE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK], +[ + AC_CACHE_CHECK( + [whether chown dereferences symlinks], + [gl_cv_func_chown_follows_symlink], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include +]GL_MDA_DEFINES[ + int + main () + { + int result = 0; + 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. */ + if (chown (dangling_symlink, getuid (), getgid ()) == 0) + result |= 1; + if (errno != ENOENT) + result |= 2; + return result; + } + ]])], + [gl_cv_func_chown_follows_symlink=yes], + [gl_cv_func_chown_follows_symlink=no], + [gl_cv_func_chown_follows_symlink="guessing yes"] + ) + ] + ) + + case "$gl_cv_func_chown_follows_symlink" in + *yes) ;; + *) + AC_DEFINE([CHOWN_MODIFIES_SYMLINK], [1], + [Define if chown modifies symlinks.]) + ;; + esac +]) diff --git a/gnulib/import/m4/gnulib-cache.m4 b/gnulib/import/m4/gnulib-cache.m4 index ad7db9a694e..d21f54296d6 100644 --- a/gnulib/import/m4/gnulib-cache.m4 +++ b/gnulib/import/m4/gnulib-cache.m4 @@ -40,6 +40,7 @@ # --no-vc-files \ # alloca \ # canonicalize-lgpl \ +# chown \ # count-one-bits \ # dirent \ # dirfd \ @@ -85,6 +86,7 @@ gl_LOCAL_DIR([]) gl_MODULES([ alloca canonicalize-lgpl + chown count-one-bits dirent dirfd diff --git a/gnulib/import/m4/gnulib-comp.m4 b/gnulib/import/m4/gnulib-comp.m4 index 75fe076f74e..d4734854fbc 100644 --- a/gnulib/import/m4/gnulib-comp.m4 +++ b/gnulib/import/m4/gnulib-comp.m4 @@ -57,6 +57,7 @@ AC_DEFUN([gl_EARLY], # Code from module canonicalize-lgpl: # Code from module chdir: # Code from module chdir-long: + # Code from module chown: # Code from module clock-time: # Code from module cloexec: # Code from module close: @@ -268,6 +269,14 @@ AC_DEFUN([gl_INIT], AC_LIBOBJ([chdir-long]) gl_PREREQ_CHDIR_LONG fi + gl_FUNC_CHOWN + if test $HAVE_CHOWN = 0 || test $REPLACE_CHOWN = 1; then + AC_LIBOBJ([chown]) + fi + if test $REPLACE_CHOWN = 1 && test $ac_cv_func_fchown = no; then + AC_LIBOBJ([fchown-stub]) + fi + gl_UNISTD_MODULE_INDICATOR([chown]) gl_CLOCK_TIME gl_MODULE_INDICATOR_FOR_TESTS([cloexec]) gl_FUNC_CLOSE @@ -968,6 +977,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/cdefs.h lib/chdir-long.c lib/chdir-long.h + lib/chown.c lib/cloexec.c lib/cloexec.h lib/close.c @@ -991,6 +1001,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/exitfail.c lib/exitfail.h lib/fchdir.c + lib/fchown-stub.c lib/fcntl.c lib/fcntl.in.h lib/fd-hook.c @@ -1189,6 +1200,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/builtin-expect.m4 m4/canonicalize.m4 m4/chdir-long.m4 + m4/chown.m4 m4/clock_time.m4 m4/close.m4 m4/closedir.m4 diff --git a/gnulib/update-gnulib.sh b/gnulib/update-gnulib.sh index e8bb5965269..44e8db47e2b 100755 --- a/gnulib/update-gnulib.sh +++ b/gnulib/update-gnulib.sh @@ -32,6 +32,7 @@ IMPORTED_GNULIB_MODULES="\ alloca \ canonicalize-lgpl \ + chown \ count-one-bits \ dirent \ dirfd \ -- 2.30.2