Hi Paul, > I installed the attached patch to Gnulib in preparation for the upcoming > glibc fix. The patch causes fchmodat with AT_SYMLINK_NOFOLLOW to work on > non-symlinks, and similarly for lchmod on non-symlinks. The idea is to > avoid this sort of problem in the future, and to let Coreutils etc. work > on older platforms as if glibc 2.32 (or whatever) is already in place.
Some improvements: 1) Improve the cross-compilation guesses. The result of the "fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks" test is: - yes on kFreeBSD/glibc, Hurd/glibc, FreeBSD 12, AIX 7.2, Solaris 11, Haiku, - no on Linux/glibc, Cygwin 2.9. 2) On Cygwin, the functions fchmodat and lchown crash. The cause is an endless recursion, because some of the #includes in fchmodat.c includes the full <sys/stat.h>, including the '#define fchmodat rpl_fchmodat'. 3) Strengthen the unit test, and make sure that it does not write files that other unit tests could possibly write as well. This test is a bit tricky, because on native Windows, we cannot do arbitrary chmods: - chmod of 700 is equivalent to 600 (since it does not have an execute bit on the file system), - chmod of 600 sets the mode to 666 - since there is no distinction between users, group, and world with this API. - After a chmod of 400 (= read-only), unlink() fails. 2020-02-08 Bruno Haible <br...@clisp.org> fchmodat: Strengthen tests. * tests/test-fchmodat.c (BASE): New macro. (main): Use it, to avoid conflicts with other unit tests. Verify that fchmodat changed the file permission bits. 2020-02-08 Bruno Haible <br...@clisp.org> fchmodat: Fix endless recursion on Cygwin (regression from 2020-02-07). * lib/fchmodat.c (orig_fchmodat): Move definition to immediately after '#undef __need_system_sys_stat_h'. 2020-02-08 Bruno Haible <br...@clisp.org> fchmodat: Improve cross-compilation guesses. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Require AC_CANONICAL_HOST. When cross-compiling, guess depending on the platform. * doc/posix-functions/fchmodat.texi: Clarify.
>From a680228fe4d39f749cb819e45202c6fec6ca9d29 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 8 Feb 2020 20:38:01 +0100 Subject: [PATCH 1/3] fchmodat: Improve cross-compilation guesses. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Require AC_CANONICAL_HOST. When cross-compiling, guess depending on the platform. * doc/posix-functions/fchmodat.texi: Clarify. --- ChangeLog | 7 +++++++ doc/posix-functions/fchmodat.texi | 10 +++++----- m4/fchmodat.m4 | 14 +++++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index df48e88..32d9a00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2020-02-08 Bruno Haible <br...@clisp.org> + fchmodat: Improve cross-compilation guesses. + * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Require AC_CANONICAL_HOST. When + cross-compiling, guess depending on the platform. + * doc/posix-functions/fchmodat.texi: Clarify. + +2020-02-08 Bruno Haible <br...@clisp.org> + Fix compilation errors in a testdir created with --with-c++-tests. * lib/c++defs.h (_GL_CXXALIASWARN1_2): Do not use __typeof__ (func), since it does not work any more with g++ >= 4.4. diff --git a/doc/posix-functions/fchmodat.texi b/doc/posix-functions/fchmodat.texi index 4d19031..a295f83 100644 --- a/doc/posix-functions/fchmodat.texi +++ b/doc/posix-functions/fchmodat.texi @@ -9,15 +9,15 @@ Gnulib module: fchmodat Portability problems fixed by Gnulib: @itemize @item -When given the @code{AT_SYMLINK_NOFOLLOW} flag, -this function fails with @code{errno} set to @code{ENOTSUP}, -even when the file is not a symbolic link: -GNU/Linux and Cygwin with glibc 2.31. -@item This function is missing on some platforms: glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, Cygwin 1.5.x, mingw, MSVC 14. But the replacement function is not safe to be used in libraries and is not multithread-safe. +@item +When given the @code{AT_SYMLINK_NOFOLLOW} flag, +this function fails with @code{errno} set to @code{ENOTSUP}, +even when the file is not a symbolic link: +GNU/Linux with glibc 2.31, Cygwin 2.9. @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4 index 8195ef6..f284485 100644 --- a/m4/fchmodat.m4 +++ b/m4/fchmodat.m4 @@ -1,4 +1,4 @@ -# fchmodat.m4 serial 2 +# fchmodat.m4 serial 3 dnl Copyright (C) 2004-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,6 +10,7 @@ AC_DEFUN([gl_FUNC_FCHMODAT], [ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CHECK_FUNCS_ONCE([fchmodat lchmod]) if test $ac_cv_func_fchmodat != yes; then HAVE_FCHMODAT=0 @@ -17,7 +18,9 @@ AC_DEFUN([gl_FUNC_FCHMODAT], AC_CACHE_CHECK( [whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks], [gl_cv_func_fchmodat_works], - [AC_RUN_IFELSE( + [dnl This test fails on GNU/Linux with glibc 2.31 (but not on + dnl GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9. + AC_RUN_IFELSE( [AC_LANG_PROGRAM( [ AC_INCLUDES_DEFAULT[ @@ -53,7 +56,12 @@ AC_DEFUN([gl_FUNC_FCHMODAT], ]])], [gl_cv_func_fchmodat_works=yes], [gl_cv_func_fchmodat_works=no], - [gl_cv_func_fchmodat_works=$gl_cross_guess_normal]) + [case "$host_os" in + dnl Guess no on Linux with glibc and Cygwin, yes otherwise. + linux-gnu* | cygwin*) gl_cv_func_fchmodat_works="guessing no" ;; + *) gl_cv_func_fchmodat_works="$gl_cross_guess_normal" ;; + esac + ]) rm -f conftest.fchmodat]) case $gl_cv_func_fchmodat_works in *yes) ;; -- 2.7.4
>From 1bbbce29dc592833e79ab6d21472528a01ab67b2 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 8 Feb 2020 20:41:20 +0100 Subject: [PATCH 2/3] fchmodat: Fix endless recursion on Cygwin (regression from 2020-02-07). * lib/fchmodat.c (orig_fchmodat): Move definition to immediately after '#undef __need_system_sys_stat_h'. --- ChangeLog | 6 ++++++ lib/fchmodat.c | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 32d9a00..a5ca210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-02-08 Bruno Haible <br...@clisp.org> + fchmodat: Fix endless recursion on Cygwin (regression from 2020-02-07). + * lib/fchmodat.c (orig_fchmodat): Move definition to immediately after + '#undef __need_system_sys_stat_h'. + +2020-02-08 Bruno Haible <br...@clisp.org> + fchmodat: Improve cross-compilation guesses. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Require AC_CANONICAL_HOST. When cross-compiling, guess depending on the platform. diff --git a/lib/fchmodat.c b/lib/fchmodat.c index c6b8ef7..87aa0d1 100644 --- a/lib/fchmodat.c +++ b/lib/fchmodat.c @@ -26,12 +26,6 @@ #include <sys/stat.h> #undef __need_system_sys_stat_h -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - #if HAVE_FCHMODAT static int orig_fchmodat (int dir, char const *file, mode_t mode, int flags) @@ -40,6 +34,12 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags) } #endif +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + #ifdef __osf__ /* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc eliminates this include because of the preliminary #include <sys/stat.h> -- 2.7.4
>From c2d184186846851f173bec9e60781a05001837c6 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 8 Feb 2020 20:47:58 +0100 Subject: [PATCH 3/3] fchmodat: Strengthen tests. * tests/test-fchmodat.c (BASE): New macro. (main): Use it, to avoid conflicts with other unit tests. Verify that fchmodat changed the file permission bits. --- ChangeLog | 7 +++++++ tests/test-fchmodat.c | 14 +++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5ca210..fc07914 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2020-02-08 Bruno Haible <br...@clisp.org> + fchmodat: Strengthen tests. + * tests/test-fchmodat.c (BASE): New macro. + (main): Use it, to avoid conflicts with other unit tests. Verify that + fchmodat changed the file permission bits. + +2020-02-08 Bruno Haible <br...@clisp.org> + fchmodat: Fix endless recursion on Cygwin (regression from 2020-02-07). * lib/fchmodat.c (orig_fchmodat): Move definition to immediately after '#undef __need_system_sys_stat_h'. diff --git a/tests/test-fchmodat.c b/tests/test-fchmodat.c index df0f604..f6b695b 100644 --- a/tests/test-fchmodat.c +++ b/tests/test-fchmodat.c @@ -28,6 +28,8 @@ SIGNATURE_CHECK (fchmodat, int, (int, const char *, mode_t, int)); #include "macros.h" +#define BASE "test-fchmodat." + int main (void) { @@ -47,9 +49,15 @@ main (void) /* Test that fchmodat works on non-symlinks, when given the AT_SYMLINK_NOFOLLOW flag. */ { - ASSERT (close (creat ("file", 0600)) == 0); - ASSERT (fchmodat (AT_FDCWD, "file", 0700, AT_SYMLINK_NOFOLLOW) == 0); - ASSERT (unlink ("file") == 0); + struct stat statbuf; + unlink (BASE "file"); + ASSERT (close (creat (BASE "file", 0600)) == 0); + ASSERT (fchmodat (AT_FDCWD, BASE "file", 0400, AT_SYMLINK_NOFOLLOW) == 0); + ASSERT (stat (BASE "file", &statbuf) >= 0); + ASSERT ((statbuf.st_mode & 0700) == 0400); + /* Clean up. */ + ASSERT (chmod (BASE "file", 0600) == 0); + ASSERT (unlink (BASE "file") == 0); } return 0; -- 2.7.4