+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
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:
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.
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:
#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
}
/* 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++)
{
-# 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,
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
-# 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,
esac
case $host_os in
- solaris*)
+ darwin* | solaris*)
REPLACE_FSTATAT=1 ;;
esac
-# serial 33
+# serial 33.1
# Copyright (C) 1997-2001, 2003-2023 Free Software Foundation, Inc.
#
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
-# serial 18
+# serial 18.1
# Copyright (C) 2009-2023 Free Software Foundation, Inc.
#
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
;;