From: Collin Funk Date: Wed, 19 Mar 2025 04:50:00 +0000 (-0700) Subject: futimens: Work around a GNU/Hurd bug. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=23a3940f61f46e84067c4b472920e1c7d34459c2;p=gnulib.git futimens: Work around a GNU/Hurd bug. * m4/futimens.m4 (gl_FUNC_FUTIMENS): Check if futimens validates the tv_nsec values of the timespec argument. Set bits in a return value instead of exiting early. * doc/posix-functions/futimens.texi (futimens): Mention the GNU/Hurd bug. Mention the same bug occurs on NetBSD 10. --- diff --git a/ChangeLog b/ChangeLog index a0a8763da1..eb51b0f33a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2025-03-18 Collin Funk + futimens: Work around a GNU/Hurd bug. + * m4/futimens.m4 (gl_FUNC_FUTIMENS): Check if futimens validates the + tv_nsec values of the timespec argument. Set bits in a return value + instead of exiting early. + * doc/posix-functions/futimens.texi (futimens): Mention the GNU/Hurd + bug. Mention the same bug occurs on NetBSD 10. + mountlist: Add tests. * modules/mountlist-tests: New file. * tests/test-mountlist.c: New file. diff --git a/doc/posix-functions/futimens.texi b/doc/posix-functions/futimens.texi index 74c3301433..61520789c1 100644 --- a/doc/posix-functions/futimens.texi +++ b/doc/posix-functions/futimens.texi @@ -31,6 +31,11 @@ Linux kernel 2.6.32, macOS 14, NetBSD 10.0, Solaris 11.1. Passing @code{AT_FDCWD} as the fd argument does not properly fail with @code{EBADF} on some systems: glibc 2.11, musl libc, Solaris 11. +@item +Out-of-range values of @code{tv_nsec} do not lead to a failure on some +platforms: +@c https://sourceware.org/bugzilla/show_bug.cgi?id=32803 +NetBSD 10.0, GNU/Hurd. @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/futimens.m4 b/m4/futimens.m4 index fe89fdffa1..7252dd66d1 100644 --- a/m4/futimens.m4 +++ b/m4/futimens.m4 @@ -1,5 +1,5 @@ # futimens.m4 -# serial 11 +# serial 12 dnl Copyright (C) 2009-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, @@ -32,22 +32,45 @@ AC_DEFUN([gl_FUNC_FUTIMENS], ]GL_MDA_DEFINES], [[struct timespec ts[2]; int fd = creat ("conftest.file", 0600); + int result = 0; struct stat st; - if (fd < 0) return 1; + if (fd < 0) + return 1; ts[0].tv_sec = 1; ts[0].tv_nsec = UTIME_OMIT; ts[1].tv_sec = 1; ts[1].tv_nsec = UTIME_NOW; errno = 0; - if (futimens (AT_FDCWD, NULL) == 0) return 2; - if (errno != EBADF) return 3; - if (futimens (fd, ts)) return 4; + if (futimens (AT_FDCWD, NULL) == 0 || errno != EBADF) + result |= 2; + if (futimens (fd, ts)) + result |= 4; sleep (1); ts[0].tv_nsec = UTIME_NOW; ts[1].tv_nsec = UTIME_OMIT; - if (futimens (fd, ts)) return 5; - if (fstat (fd, &st)) return 6; - if (st.st_ctime < st.st_atime) return 7; + if (futimens (fd, ts)) + result |= 8; + if (fstat (fd, &st)) + result |= 16; + if (st.st_ctime < st.st_atime) + result |= 32; + enum + { + BILLION = 1000 * 1000 * 1000, + /* Bogus positive and negative tv_nsec values closest to valid + range, but without colliding with UTIME_NOW or UTIME_OMIT. */ + UTIME_BOGUS_POS = BILLION + ((UTIME_NOW == BILLION || UTIME_OMIT == BILLION) + ? (1 + (UTIME_NOW == BILLION + 1) + + (UTIME_OMIT == BILLION + 1)) + : 0) + }; + ts[0].tv_sec = 1; + ts[0].tv_nsec = UTIME_BOGUS_POS; + ts[1].tv_sec = 1; + ts[1].tv_nsec = 0; + if (futimens (fd, ts) == 0) + result |= 64; + return result; ]])], [gl_cv_func_futimens_works=yes], [gl_cv_func_futimens_works=no],