On 2023-12-24 20:56, Gordon Steemson wrote:
I ran the "make installcheck" tests merely as a matter of excessive
thoroughness, and was therefore quite surprised to get a few failures.
All three were to do with unreadable directories; either lacking read
permissions, or simply absent by the time of access.

Thanks for the bug report; this helped us to identify a macOS bug that affects many GNU programs, albeit only on artificially-generated files.

Although Apple no longer supports the Darwin 8.11.0 / Mac OS X 10.4.11 "Tiger" (2007) system that you ran your tests on, I ran the GNU Tar tests on Darwin 21.6.0 / macOS 12.6 "Monterey" 21G115 (2022), found some of the issues that you mentioned, and fixed them by installing the attached patches.

These patches mostly just work around macOS bugs. One of the macOS bugs affects GNU Tar, but only on files with artificial timestamps dating before 1970; this bug is fixed by the first attached patch, which is to Gnulib (which is shared among various GNU packages). Two macOS bugs simply cause GNU Tar's test cases to mistakenly report an error, and there is one portability bug in the GNU Tar test cases; the remaining three patches are to GNU Tar, and fix these bugs.

These fixes should appear in the next release of GNU Tar. In the meantime the GNU Tar that you built should be good enough, unless you have files with timestamps before 1970.
From 00cf42bb77bb69f680f38e278155a425875cf37b Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Thu, 28 Dec 2023 11:15:56 -0800
Subject: [PATCH] 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.
---
 ChangeLog                        | 17 +++++++++++++++++
 doc/posix-functions/fstat.texi   |  7 ++++---
 doc/posix-functions/fstatat.texi |  7 ++++---
 doc/posix-functions/lstat.texi   |  7 ++++---
 doc/posix-functions/stat.texi    |  7 ++++---
 lib/stat-time.h                  | 13 ++++++++-----
 m4/fstat.m4                      |  6 +++---
 m4/fstatat.m4                    |  4 ++--
 m4/lstat.m4                      |  4 ++--
 m4/stat.m4                       |  6 +++---
 10 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 46c2f77242..746a1ea70f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2023-12-28  Paul Eggert  <egg...@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  <br...@clisp.org>
 
 	jit/cache: Fix compilation error on m68k, sparc, etc.
diff --git a/doc/posix-functions/fstat.texi b/doc/posix-functions/fstat.texi
index b4c2431ff4..e8ef324553 100644
--- a/doc/posix-functions/fstat.texi
+++ b/doc/posix-functions/fstat.texi
@@ -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
diff --git a/doc/posix-functions/fstatat.texi b/doc/posix-functions/fstatat.texi
index 49d394addf..e959a5cc73 100644
--- a/doc/posix-functions/fstatat.texi
+++ b/doc/posix-functions/fstatat.texi
@@ -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:
diff --git a/doc/posix-functions/lstat.texi b/doc/posix-functions/lstat.texi
index f0a6ffb572..95f740ce09 100644
--- a/doc/posix-functions/lstat.texi
+++ b/doc/posix-functions/lstat.texi
@@ -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.
diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi
index b64bdd3a01..f655451392 100644
--- a/doc/posix-functions/stat.texi
+++ b/doc/posix-functions/stat.texi
@@ -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:
diff --git a/lib/stat-time.h b/lib/stat-time.h
index 75eb27e549..1488182163 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -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++)
         {
diff --git a/m4/fstat.m4 b/m4/fstat.m4
index 382741f412..769e7d6e58 100644
--- a/m4/fstat.m4
+++ b/m4/fstat.m4
@@ -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
diff --git a/m4/fstatat.m4 b/m4/fstatat.m4
index 083076911f..84f82a2a69 100644
--- a/m4/fstatat.m4
+++ b/m4/fstatat.m4
@@ -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
 
diff --git a/m4/lstat.m4 b/m4/lstat.m4
index 977386348a..76932d55a8 100644
--- a/m4/lstat.m4
+++ b/m4/lstat.m4
@@ -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
diff --git a/m4/stat.m4 b/m4/stat.m4
index 81bd16a8f4..6e7be3d1c5 100644
--- a/m4/stat.m4
+++ b/m4/stat.m4
@@ -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
       ;;
-- 
2.40.1

From 835b0c7dee65e943554d58a925ef188a5399c85a Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 1 Jan 2024 19:09:59 -0800
Subject: [PATCH 1/3] Port --numeric-owner basic tests to macOS

* tests/numeric.at: If chown fails, skip the test.
This is needed on macOS 12.6 if the user has group
ID 4294967295 (nogroup), which chown rejects.
---
 tests/numeric.at | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/numeric.at b/tests/numeric.at
index 4a3c2a2a..4d81142c 100644
--- a/tests/numeric.at
+++ b/tests/numeric.at
@@ -34,7 +34,7 @@ MYGRP=$(id -gn) || AT_SKIP_TEST
 
 mkdir dir
 # Ensure correct group id on BSDs.
-chown :$MYGID dir >/dev/null 2>/dev/null
+chown :$MYGID dir || AT_SKIP_TEST
 genfile --file dir/file
 
 
@@ -74,4 +74,3 @@ OK
 AT_CLEANUP
 
 m4_popdef([TESTOP])
-
-- 
2.40.1

From 24a2fcfd83b6560b238cc8765da2398a44d311ba Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 1 Jan 2024 19:09:59 -0800
Subject: [PATCH 2/3] Skip test on macOS 12.6
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* tests/xform04.at: Skip test on macOS 12.6, which is behind the times
and doesn’t think that ⱥ (U+2C65 LATIN SMALL LETTER A WITH STROKE) is
printable.
---
 tests/xform04.at | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/xform04.at b/tests/xform04.at
index a2c80898..57a3fb8e 100644
--- a/tests/xform04.at
+++ b/tests/xform04.at
@@ -39,6 +39,8 @@ if test "`(locale charmap) 2>/dev/null`" != UTF-8; then
   done
 fi
 
+expr Aa.Ⱥⱥ : 'Aa\.[[:print:]][[:print:]]$' >/dev/null || AT_SKIP_TEST
+
 genfile --file Aa.Ⱥⱥ
 tar -cvf /dev/null --transform='s/.*/\L&-\U&/' --show-transformed-name Aa.Ⱥⱥ],
 [0],
-- 
2.40.1

From 66eaa2f821d45f38220f303e4f422f943f0b307a Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 1 Jan 2024 19:09:59 -0800
Subject: [PATCH 3/3] Port EOF detection test to macOS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* tests/delete06.at: Don’t assume the diagnostic is
“Value too large for defined data type”, as strerror
uses a different wording on macOS 12.6.
---
 tests/delete06.at | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tests/delete06.at b/tests/delete06.at
index 41e53c22..ee5d9853 100644
--- a/tests/delete06.at
+++ b/tests/delete06.at
@@ -38,8 +38,6 @@ tar --delete 'b/' -f trunc.tar
 ],
 [2],
 [],
-[tar: lseek: trunc.tar: Value too large for defined data type
-tar: Exiting with failure status due to previous errors
-],[],[],[gnu, pax])
+[stderr],[],[],[gnu, pax])
 
 AT_CLEANUP
-- 
2.40.1

Reply via email to