gnulib: import chown
authorMike Frysinger <vapier@gentoo.org>
Sat, 29 May 2021 16:10:38 +0000 (12:10 -0400)
committerMike Frysinger <vapier@gentoo.org>
Tue, 8 Jun 2021 04:12:43 +0000 (00:12 -0400)
A few sims use this to emulate chown syscalls.

13 files changed:
gnulib/ChangeLog
gnulib/Makefile.in
gnulib/aclocal.m4
gnulib/config.in
gnulib/configure
gnulib/import/Makefile.am
gnulib/import/Makefile.in
gnulib/import/chown.c [new file with mode: 0644]
gnulib/import/fchown-stub.c [new file with mode: 0644]
gnulib/import/m4/chown.m4 [new file with mode: 0644]
gnulib/import/m4/gnulib-cache.m4
gnulib/import/m4/gnulib-comp.m4
gnulib/update-gnulib.sh

index 1563e04119b1326f42d6806b43057d8c2fc8225d..f5a0a32cb4fb3cb9a0f95bb46c583897f0233622 100644 (file)
@@ -1,3 +1,11 @@
+2021-06-08  Mike Frysinger  <vapier@gentoo.org>
+
+       * 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  <vapier@gentoo.org>
 
        * update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add ffs.
index 4c46e0a99e72d89bfefefa1588e91fb8b11c2152..04dc454701e116d83e7304400e03a01463dae78c 100644 (file)
@@ -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 \
index 00a0c9c0d95ff2b39e93dab6e39be9bc02de5672..d466a2666cacbd4db82a7b6ecf04761f598c5469 100644 (file)
@@ -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])
index e3f581423f9f3cc5c022898072b336e9cfd5107a..15abb17cb44545afdda9b3662e8c1c01bce99a05 100644 (file)
 /* 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
 
 /* 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
 
 /* 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
 
 /* 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
 
index 2ddb1d7cbb074e5c3729c827671aaa36f3da9638..827393a6d254e0c6fc8d070c7d3ee5859a2a4a3a 100644 (file)
@@ -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 <sys/types.h>
 
+_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 <fcntl.h>
+
+
+$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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+$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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+$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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+$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;
+
+
+
+
 
 
 
     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 <sys/types.h>
-
-_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.
index e99adab7a22cf655da0e79dc1e8d4e72087da798..30b8afd2846373d38dfa7cecba7d66c1574ca2e4 100644 (file)
@@ -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
index e02adc633ea6e6c41a519b829c19be0501ad3f7c..d8a31f83de465cc6ad3cdaf6ce1888c375634ff4 100644 (file)
@@ -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 (file)
index 0000000..9b8b361
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#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 (file)
index 0000000..f549ff3
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert, 2004.  */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+
+/* 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 (file)
index 0000000..d1c0831
--- /dev/null
@@ -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 <fcntl.h>
+          ]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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+]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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+]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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+]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
+])
index ad7db9a694ec9312750b5d60fdd0f9f7c4587a7f..d21f54296d62ffb9b51a0a661d9b270ebef16a48 100644 (file)
@@ -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
index 75fe076f74ec9dbf2ff899be291dbca80e015e43..d4734854fbc10e0abff5b7bb8d5ffdde5d4642c7 100644 (file)
@@ -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
index e8bb59652696176ef610adee43a8881ec56fd808..44e8db47e2ba53f2285e933c407c34d60c39fe68 100755 (executable)
@@ -32,6 +32,7 @@
 IMPORTED_GNULIB_MODULES="\
     alloca \
     canonicalize-lgpl \
+    chown \
     count-one-bits \
     dirent \
     dirfd \