]> Savannah Git Hosting - gnulib.git/commitdiff
stat-time: fix macOS bug with negative file times stable-202301
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 28 Dec 2023 19:15:56 +0000 (11:15 -0800)
committerBruno Haible <bruno@clisp.org>
Thu, 18 Jan 2024 08:14:35 +0000 (09:14 +0100)
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/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 4c418233a0f9d9d997c7a1fa17b060cb6f5a4e7d..c7c47be0148cbd7f48ac6a08d3c91fd648f12d8b 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-10  Pádraig Brady  <P@draigBrady.com>
 
        bootstrap: fix option propagation with --bootstrap-sync
index a37ee428b6c9a2a8ab0a60f050e78e9061920d50..664ffe772851a140fce8a3b9e0423be1f81506fa 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 31b7759d95cab92032c00d8328d5f14dd25eb7cd..eb666f88eaf63f5487dc1015041827241595abf7 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 0e3f56a96d1c510d6053e3aa89114deea34f2ebb..2f4d277843445870ce035a812ac71fa853c3cd33 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 92aa1e64e20aec776f3300dc3d2e19dcde7c4d08..50cfa61eff7c1f82fac8332ecb9d34507b9aeba2 100644 (file)
@@ -49,11 +49,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
@@ -202,20 +204,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 7cb2edb001611229d2a892909454b2eb9a15858b..eb55bcd2a82e748889a74c50cfc93a8d0d4ca6f4 100644 (file)
@@ -1,4 +1,4 @@
-# fstat.m4 serial 8
+# fstat.m4 serial 8.1
 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* | solaris*)
+    darwin* | mingw* | 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 7e667fb187a3f14af5a5380267aa9223d98cef55..125a73a16edd0ba95d29fd8341604efaeffcc65a 100644 (file)
@@ -1,4 +1,4 @@
-# serial 33
+# serial 33.1
 
 # 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 4d241e27a17cfe5be4bb7741baef56077ca2c398..65ba6073559407e18113f631aec744ebc93664d1 100644 (file)
@@ -1,4 +1,4 @@
-# serial 18
+# serial 18.1
 
 # Copyright (C) 2009-2023 Free Software Foundation, Inc.
 #
@@ -59,8 +59,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
       ;;