]> Savannah Git Hosting - gnulib.git/commitdiff
stat-time: fix macOS bug with negative file times
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 28 Dec 2023 19:15:56 +0000 (11:15 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 28 Dec 2023 19:18:26 +0000 (11:18 -0800)
macOS has a bug similar (but not identical) to Solaris when
file timestamps are negative: tv_nsec might go negative.
Problem reported on Darwin 8.11.0 for GNU Tar by Gordon Steemson in:
https://lists.gnu.org/r/bug-tar/2023-12/msg00001.html
This was evidently Mac OS X 10.4.11; I reproduced it on
Darwin 21.6.0 (macOS 12.5).
* lib/stat-time.h (STAT_TIMESPEC_OFFSETOF): New macro.
(stat_time_normalize): Also normalize timestamps on macOS.
* m4/fstat.m4 (gl_FUNC_FSTAT):
* m4/fstatat.m4 (gl_FUNC_FSTATAT):
* m4/lstat.m4 (gl_FUNC_LSTAT):
* m4/stat.m4 (gl_FUNC_STAT):
Also replace on macOS.

ChangeLog
doc/posix-functions/fstat.texi
doc/posix-functions/fstatat.texi
doc/posix-functions/lstat.texi
doc/posix-functions/stat.texi
lib/stat-time.h
m4/fstat.m4
m4/fstatat.m4
m4/lstat.m4
m4/stat.m4

index 46c2f772428184413c407ac8835ae6681e0f600f..746a1ea70fe910edc383f834dfaced0c262bd02b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2023-12-28  Paul Eggert  <eggert@cs.ucla.edu>
+
+       stat-time: fix macOS bug with negative file times
+       macOS has a bug similar (but not identical) to Solaris when
+       file timestamps are negative: tv_nsec might go negative.
+       Problem reported on Darwin 8.11.0 for GNU Tar by Gordon Steemson in:
+       https://lists.gnu.org/r/bug-tar/2023-12/msg00001.html
+       This was evidently Mac OS X 10.4.11; I reproduced it on
+       Darwin 21.6.0 (macOS 12.5).
+       * lib/stat-time.h (STAT_TIMESPEC_OFFSETOF): New macro.
+       (stat_time_normalize): Also normalize timestamps on macOS.
+       * m4/fstat.m4 (gl_FUNC_FSTAT):
+       * m4/fstatat.m4 (gl_FUNC_FSTATAT):
+       * m4/lstat.m4 (gl_FUNC_LSTAT):
+       * m4/stat.m4 (gl_FUNC_STAT):
+       Also replace on macOS.
+
 2023-12-19  Bruno Haible  <bruno@clisp.org>
 
        jit/cache: Fix compilation error on m68k, sparc, etc.
index b4c2431ff413d16ec408ed9224099cf8aaf76707..e8ef3245538e65a7452ba4b1fe205fa0fdd25fe1 100644 (file)
@@ -21,10 +21,11 @@ access files that happen to have a 64-bit inode number.  This can occur with
 file systems such as XFS (typically on large disks) and NFS.
 @xref{Large File Support}.
 @item
-On Solaris 11.4, when this function yields a timestamp with a
+On macOS 12.6, when this function yields a timestamp with a
 nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range
-@minus{}1000000000..@minus{}1, representing a negative nanoseconds
-offset from @code{tv_sec}.
+@minus{}999999999..@minus{}1, representing a negative nanoseconds
+offset from @code{tv_sec}.  Solaris 11.4 is similar, except that
+@code{tv_sec} might also be @minus{}1000000000.
 @item
 The @code{st_atime}, @code{st_ctime}, @code{st_mtime} fields are affected by
 the current time zone and by the DST flag of the current time zone on some
index 49d394addf14ebc02c8f254e7c38a3fbe3f6a17d..e959a5cc7377567b347f1642bb6c889157180fe4 100644 (file)
@@ -26,10 +26,11 @@ For symlinks, when the argument ends in a slash, some platforms don't
 dereference the argument:
 Solaris 9.
 @item
-On Solaris 11.4, when this function yields a timestamp with a
+On macOS 12.6, when this function yields a timestamp with a
 nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range
-@minus{}1000000000..@minus{}1, representing a negative nanoseconds
-offset from @code{tv_sec}.
+@minus{}999999999..@minus{}1, representing a negative nanoseconds
+offset from @code{tv_sec}.  Solaris 11.4 is similar, except that
+@code{tv_sec} might also be @minus{}1000000000.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index f0a6ffb572f8432acb192667390ab88d89743faa..95f740ce09b60f63f6ae38273bff7fc6ed349945 100644 (file)
@@ -26,10 +26,11 @@ On some platforms, @code{lstat("file/",buf)} succeeds instead of
 failing with @code{ENOTDIR}.
 macOS 11.1, Solaris 9.
 @item
-On Solaris 11.4, when this function yields a timestamp with a
+On macOS 12.6, when this function yields a timestamp with a
 nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range
-@minus{}1000000000..@minus{}1, representing a negative nanoseconds
-offset from @code{tv_sec}.
+@minus{}999999999..@minus{}1, representing a negative nanoseconds
+offset from @code{tv_sec}.  Solaris 11.4 is similar, except that
+@code{tv_sec} might also be @minus{}1000000000.
 @item
 On Windows platforms (excluding Cygwin), symlinks are not supported, so
 @code{lstat} does not exist.
index b64bdd3a016004a75c993cb5f4011f46c5476b77..f655451392784616dc47694cc968ec727edba44f 100644 (file)
@@ -35,10 +35,11 @@ On some platforms, @code{stat(".",buf)} and @code{stat("./",buf)} give
 different results:
 mingw, MSVC 14.
 @item
-On Solaris 11.4, when this function yields a timestamp with a
+On macOS 12.6, when this function yields a timestamp with a
 nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range
-@minus{}1000000000..@minus{}1, representing a negative nanoseconds
-offset from @code{tv_sec}.
+@minus{}999999999..@minus{}1, representing a negative nanoseconds
+offset from @code{tv_sec}.  Solaris 11.4 is similar, except that
+@code{tv_sec} might also be @minus{}1000000000.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 75eb27e549d413f36a906f3fc700bcc6f322a559..14881821631441a644ea9a0d48d7694bb18d1818 100644 (file)
@@ -52,11 +52,13 @@ extern "C" {
 #if _GL_WINDOWS_STAT_TIMESPEC || defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
 # if _GL_WINDOWS_STAT_TIMESPEC || defined TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
 #  define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+#  define STAT_TIMESPEC_OFFSETOF(st_xtim) offsetof (struct stat, st_xtim)
 # else
 #  define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
 # endif
 #elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
 # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
+# define STAT_TIMESPEC_OFFSETOF(st_xtim) offsetof (struct stat, st_xtim##espec)
 #elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
 # define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
 #elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
@@ -194,20 +196,21 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
 }
 
 /* If a stat-like function returned RESULT, normalize the timestamps
-   in *ST, in case this platform suffers from the Solaris 11 bug where
+   in *ST, if this platform suffers from a macOS and Solaris bug where
    tv_nsec might be negative.  Return the adjusted RESULT, setting
    errno to EOVERFLOW if normalization overflowed.  This function
    is intended to be private to this .h file.  */
 _GL_STAT_TIME_INLINE int
 stat_time_normalize (int result, _GL_UNUSED struct stat *st)
 {
-#if defined __sun && defined STAT_TIMESPEC
+#if (((defined __APPLE__ && defined __MACH__) || defined __sun) \
+     && defined STAT_TIMESPEC_OFFSETOF)
   if (result == 0)
     {
       long int timespec_hz = 1000000000;
-      short int const ts_off[] = { offsetof (struct stat, st_atim),
-                                   offsetof (struct stat, st_mtim),
-                                   offsetof (struct stat, st_ctim) };
+      short int const ts_off[] = { STAT_TIMESPEC_OFFSETOF (st_atim),
+                                   STAT_TIMESPEC_OFFSETOF (st_mtim),
+                                   STAT_TIMESPEC_OFFSETOF (st_ctim) };
       int i;
       for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
         {
index 382741f412dc6a8bc68fe88d39f266719fb10404..769e7d6e58ed12bfce1186e71d25b84222e46f7f 100644 (file)
@@ -1,4 +1,4 @@
-# fstat.m4 serial 9
+# fstat.m4 serial 10
 dnl Copyright (C) 2011-2023 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,10 +10,10 @@ AC_DEFUN([gl_FUNC_FSTAT],
   AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
 
   case "$host_os" in
-    mingw* | windows* | solaris*)
+    darwin* | mingw* | windows* | solaris*)
+      dnl macOS and Solaris stat can return a negative tv_nsec.
       dnl On MinGW, the original stat() returns st_atime, st_mtime,
       dnl st_ctime values that are affected by the time zone.
-      dnl Solaris stat can return a negative tv_nsec.
       REPLACE_FSTAT=1
       ;;
   esac
index 083076911ff7a1d84812246bf9762064453cd8ce..84f82a2a697b5537fdf160572e7531a50b6bfb9d 100644 (file)
@@ -1,4 +1,4 @@
-# fstatat.m4 serial 4
+# fstatat.m4 serial 5
 dnl Copyright (C) 2004-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,7 +50,7 @@ AC_DEFUN([gl_FUNC_FSTATAT],
     esac
 
     case $host_os in
-      solaris*)
+      darwin* | solaris*)
         REPLACE_FSTATAT=1 ;;
     esac
 
index 977386348adab81fcee06a648bc949b742fcbfdf..76932d55a8163fce92ddfc2370c8f4f084336de8 100644 (file)
@@ -1,4 +1,4 @@
-# serial 35
+# serial 36
 
 # Copyright (C) 1997-2001, 2003-2023 Free Software Foundation, Inc.
 #
@@ -18,7 +18,7 @@ AC_DEFUN([gl_FUNC_LSTAT],
   if test $ac_cv_func_lstat = yes; then
     AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
     case $host_os,$gl_cv_func_lstat_dereferences_slashed_symlink in
-      solaris* | *no)
+      darwin* | solaris* | *no)
         REPLACE_LSTAT=1
         ;;
     esac
index 81bd16a8f4a67e7bfc27879d252e871deaf475bc..6e7be3d1c5ee2de20930230dd7b488a448fe0864 100644 (file)
@@ -1,4 +1,4 @@
-# serial 20
+# serial 21
 
 # Copyright (C) 2009-2023 Free Software Foundation, Inc.
 #
@@ -61,8 +61,8 @@ AC_DEFUN([gl_FUNC_STAT],
             help when passed a file name with a trailing slash]);;
       esac
       case $host_os in
-        dnl Solaris stat can return a negative tv_nsec.
-        solaris*)
+        dnl macOS and Solaris stat can return a negative tv_nsec.
+        darwin* | solaris*)
           REPLACE_FSTAT=1 ;;
       esac
       ;;