+2025-09-22 Bruno Haible <bruno@clisp.org>
+
+ fchownat: Fix test failure on OpenBSD and Cygwin 2.9 (regr. 2025-09-20).
+ * doc/posix-functions/fchownat.texi: Document that the dereferencing bug
+ also affects OpenBSD and Cygwin 2.9.
+ * m4/chown.m4 (gl_FUNC_CHOWN_CTIME): New macro, extracted from
+ gl_FUNC_CHOWN.
+ (gl_FUNC_CHOWN): Invoke it.
+ * m4/fchownat.m4 (gl_FUNC_FCHOWNAT_DEREF_BUG): Guess that a platform
+ that has the chown ctime bug also has the fchownat AT_SYMLINK_NOFOLLOW
+ bug.
+ * modules/fchownat (Files): Add m4/chown.m4.
+
2025-09-21 Paul Eggert <eggert@cs.ucla.edu>
fchownat: fix recently introduced flag typo
# chown.m4
-# serial 39
+# serial 40
dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2025 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
;;
esac
- dnl OpenBSD fails to update ctime if ownership does not change.
- AC_CACHE_CHECK([whether chown updates ctime per POSIX],
- [gl_cv_func_chown_ctime_works],
- [dnl This test is tricky as it depends on timing and file timestamp
- dnl resolution, and there were false positives when configuring with
- dnl Linux fakeroot. Since the problem occurs only on OpenBSD and Cygwin,
- dnl test only on these platforms.
- AS_CASE([$host_os],
- [openbsd* | cygwin*],
- [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],
- [# Obey --enable-cross-guesses.
- gl_cv_func_chown_ctime_works="$gl_cross_guess_normal"
- ])
- rm -f conftest.file
- ],
- [gl_cv_func_chown_ctime_works=yes])
- ])
+ gl_FUNC_CHOWN_CTIME
case "$gl_cv_func_chown_ctime_works" in
*yes) ;;
*)
;;
esac
])
+
+AC_DEFUN_ONCE([gl_FUNC_CHOWN_CTIME],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CHECK_FUNCS_ONCE([chown])
+
+ dnl mingw lacks chown altogether.
+ if test $ac_cv_func_chown != no; then
+ dnl OpenBSD and Cygwin 2.9.0 fail to update ctime if ownership does not
+ dnl change.
+ AC_CACHE_CHECK([whether chown updates ctime per POSIX],
+ [gl_cv_func_chown_ctime_works],
+ [dnl This test is tricky as it depends on timing and file timestamp
+ dnl resolution, and there were false positives when configuring with
+ dnl Linux fakeroot. Since the problem occurs only on OpenBSD and Cygwin,
+ dnl test only on these platforms.
+ AS_CASE([$host_os],
+ [openbsd* | cygwin*],
+ [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],
+ [# Obey --enable-cross-guesses.
+ gl_cv_func_chown_ctime_works="$gl_cross_guess_normal"
+ ])
+ rm -f conftest.file
+ ],
+ [gl_cv_func_chown_ctime_works=yes])
+ ])
+ fi
+])
# fchownat.m4
-# serial 8
+# serial 9
dnl Copyright (C) 2004-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
AC_CACHE_CHECK([whether fchownat works with AT_SYMLINK_NOFOLLOW],
[gl_cv_func_fchownat_nofollow_works],
- [
- gl_dangle=conftest.dangle
- # Remove any remnants of a previous test.
- rm -f $gl_dangle
- # Arrange for deletion of the temporary file this test creates.
- ac_clean_files="$ac_clean_files $gl_dangle"
- ln -s conftest.no-such $gl_dangle
- AC_RUN_IFELSE(
- [AC_LANG_SOURCE(
- [[
+ [gl_FUNC_CHOWN_CTIME
+ case "$gl_cv_func_chown_ctime_works" in
+ *yes)
+ gl_dangle=conftest.dangle
+ # Remove any remnants of a previous test.
+ rm -f $gl_dangle
+ # Arrange for deletion of the temporary file this test creates.
+ ac_clean_files="$ac_clean_files $gl_dangle"
+ ln -s conftest.no-such $gl_dangle
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE(
+ [[
#include <fcntl.h>
#include <unistd.h>
/* Android 4.3 declares fchownat() in <sys/stat.h> instead. */
AT_SYMLINK_NOFOLLOW) != 0
&& errno == ENOENT);
}
- ]])],
- [gl_cv_func_fchownat_nofollow_works=yes],
- [gl_cv_func_fchownat_nofollow_works=no],
- [gl_cv_func_fchownat_nofollow_works="$gl_cross_guess_normal"])
- ])
- AS_IF([test "$gl_cv_func_fchownat_nofollow_works" != yes], [$1], [$2])
+ ]])],
+ [gl_cv_func_fchownat_nofollow_works=yes],
+ [gl_cv_func_fchownat_nofollow_works=no],
+ [gl_cv_func_fchownat_nofollow_works="$gl_cross_guess_normal"])
+ ;;
+ *)
+ dnl On OpenBSD and Cygwin 2.9.0, the test above would produce
+ dnl gl_cv_func_fchownat_nofollow_works=yes, and this would then
+ dnl lead to an fchownat test failure:
+ dnl test-lchown.h:185: assertion 'st1.st_gid == st2.st_gid' failed
+ dnl Since testing for this bug directly is only possible on machines
+ dnl where the current user is in at least two groups, we use
+ dnl gl_FUNC_CHOWN_CTIME as a substitute test.
+ gl_cv_func_fchownat_nofollow_works="guessing no"
+ ;;
+ esac
+ ])
+ case "$gl_cv_func_fchownat_nofollow_works" in
+ *yes) $2 ;;
+ *) $1 ;;
+ esac
])
# gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]])