1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-04-28 06:33:36 +00:00

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.
This commit is contained in:
Paul Eggert
2023-12-28 11:15:56 -08:00
committed by Bruno Haible
parent a2ab76186d
commit 20932856a6
9 changed files with 47 additions and 24 deletions

View File

@@ -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

View 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:

View 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.

View 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:

View 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++)
{

View 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

View 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

View 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

View 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
;;