]> Savannah Git Hosting - gnulib.git/commitdiff
utimensat: Work around a GNU/Hurd bug.
authorCollin Funk <collin.funk1@gmail.com>
Tue, 18 Mar 2025 04:16:22 +0000 (21:16 -0700)
committerBruno Haible <bruno@clisp.org>
Tue, 1 Apr 2025 14:52:05 +0000 (16:52 +0200)
* lib/utimensat.c (rpl_utimensat) [__gnu_hurd__]: Check for out of range
tv_nsec values.
* m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise. Guess that utimensat
doesn't work on GNU/Hurd.
* doc/posix-functions/utimensat.texi: Mention the bug.

ChangeLog
doc/posix-functions/utimensat.texi
lib/utimensat.c
m4/utimensat.m4

index fa88455eb53d03d1b9e34b0fd62031657362ced8..e22981469faacd51d1f9fc8c90e671178501e1a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-03-17  Collin Funk  <collin.funk1@gmail.com>
+
+       utimensat: Work around a GNU/Hurd bug.
+       * lib/utimensat.c (rpl_utimensat) [__gnu_hurd__]: Check for out of range
+       tv_nsec values.
+       * m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise. Guess that utimensat
+       doesn't work on GNU/Hurd.
+       * doc/posix-functions/utimensat.texi: Mention the bug.
+
 2025-03-13  Collin Funk  <collin.funk1@gmail.com>
 
        vma-iter: Detect executable memory segments on Haiku (regr. 2011-01-25).
index 41b30768aed5de1a0fb9a8b9abce3dd54c925a91..6547a80b6c94eaea11463fcbaaf0261e09091c59 100644 (file)
@@ -35,7 +35,8 @@ Linux kernel 2.6.32, macOS 14, NetBSD 10.0, Solaris 11.1.
 @item
 Out-of-range values of @code{tv_nsec} do not lead to a failure on some
 platforms:
-Linux kernel 2.6.22.19 on hppa, NetBSD 10.0.
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=32802
+Linux kernel 2.6.22.19 on hppa, NetBSD 10.0, GNU/Hurd.
 @item
 On some platforms, this function mis-handles a trailing slash:
 AIX 7.2.
index b44207b4bec50063751236be4a4bfeed016a269b..ca1d39e59005828916719bbf79db0c8bd9e7bd13 100644 (file)
@@ -1,5 +1,5 @@
 /* Set the access and modification time of a file relative to directory fd.
-   Copyright (C) 2009-2024 Free Software Foundation, Inc.
+   Copyright (C) 2009-2025 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
@@ -136,8 +136,9 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
         }
 #   endif
 #  endif
-#  if defined __APPLE__ && defined __MACH__
-      /* macOS 10.13 does not reject invalid tv_nsec values either.  */
+#  if (defined __APPLE__ && defined __MACH__) || defined __gnu_hurd__
+      /* macOS 10.13 and GNU Hurd do not reject invalid tv_nsec values
+         either.  */
       if (times
           && ((times[0].tv_nsec != UTIME_OMIT
                && times[0].tv_nsec != UTIME_NOW
@@ -151,6 +152,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
           errno = EINVAL;
           return -1;
         }
+#   if defined __APPLE__ && defined __MACH__
       size_t len = strlen (file);
       if (len > 0 && file[len - 1] == '/')
         {
@@ -163,6 +165,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
               return -1;
             }
         }
+#   endif
 #  endif
       result = utimensat (fd, file, times, flag);
       /* Linux kernel 2.6.25 has a bug where it returns EINVAL for
index a583f37668764563f8e4ca1930000f824c975d1d..ec7fde7bb2f55f6762b2811f1271e0a2e81e2117 100644 (file)
@@ -1,6 +1,6 @@
 # utimensat.m4
-# serial 12
-dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
+# serial 14
+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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -66,11 +66,30 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
                 ts[1].tv_sec = 1;
                 ts[1].tv_nsec = UTIME_OMIT;
                 if (utimensat (AT_FDCWD, f, ts, 0))
-                  result |= 16;
+                  result |= 8;
                 if (stat (f, &st))
-                  result |= 32;
+                  result |= 8;
                 else if (st.st_ctime < st.st_atime)
-                  result |= 64;
+                  result |= 16;
+              }
+              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)
+              };
+              {
+                struct timespec ts[2];
+                ts[0].tv_sec = 1;
+                ts[0].tv_nsec = UTIME_BOGUS_POS;
+                ts[1].tv_sec = 1;
+                ts[1].tv_nsec = 0;
+                if (utimensat (AT_FDCWD, f, ts, 0) == 0)
+                  result |= 32;
               }
               return result;
             ]])],
@@ -82,8 +101,11 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
          ],
          [case "$host_os" in
             # Guess yes on Linux or glibc systems.
-            linux-* | linux | *-gnu* | gnu*)
+            linux*)
               gl_cv_func_utimensat_works="guessing yes" ;;
+            # Guess no on GNU/Hurd.
+            gnu*)
+              gl_cv_func_utimensat_works="guessing no" ;;
             # Guess yes on systems that emulate the Linux system calls.
             midipix*)
               gl_cv_func_utimensat_works="guessing yes" ;;