On macOS 10.13, I'm seeing test failures:

FAIL: test-futimens
===================

../../gltests/test-futimens.h:170: assertion 'ctime_compare (&st3, &st2) < 0' 
failed
FAIL test-futimens (exit status: 134)

FAIL: test-utimens
==================

../../gltests/test-utimens.h:149: assertion 'ctime_compare (&st3, &st2) < 0' 
failed
FAIL test-utimens (exit status: 134)

I looked at the file timestamps using coreutils' 'stat' program. These two
failures are apparently caused by st_ctime being unchanged when you ask
for an st_atime change using utimensat(). I think this is not worth working
around, because every read access on a file causes st_atime to change without
st_ctime changing.

Another test failure, then:

./test-utimens.h:164: assertion 'func (BASE "link/", NULL) == -1' failed
Abort trap: 6


2021-01-02  Bruno Haible  <[email protected]>

        utimens: Fix test failure on macOS 10.13.
        * lib/utimens.c (fdutimens): Before calling utimensat, recognize a
        filename ending in a slash that does not point to a directory.

2021-01-02  Bruno Haible  <[email protected]>

        utimens: Avoid test failures on macOS 10.13.
        Reported by Martin Storsjö <[email protected]> in
        <https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.
        * tests/test-utimens-common.h (check_ctime): Define to -1 on macOS.
        * tests/test-utimens.h (test_utimens): Don't expect a ctime change when
        only the atime is requested to change.
        * tests/test-futimens.h (test_futimens): Likewise.
        * tests/test-lutimens.h (test_lutimens): Likewise.

From 3b123860925185b7ba330e1f24a7a9389a955f9b Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sat, 2 Jan 2021 18:57:10 +0100
Subject: [PATCH 1/2] utimens: Avoid test failures on macOS 10.13.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Reported by Martin Storsjö <[email protected]> in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.

* tests/test-utimens-common.h (check_ctime): Define to -1 on macOS.
* tests/test-utimens.h (test_utimens): Don't expect a ctime change when
only the atime is requested to change.
* tests/test-futimens.h (test_futimens): Likewise.
* tests/test-lutimens.h (test_lutimens): Likewise.
---
 ChangeLog                   | 11 +++++++++++
 tests/test-futimens.h       |  2 +-
 tests/test-lutimens.h       |  2 +-
 tests/test-utimens-common.h |  3 +++
 tests/test-utimens.h        |  2 +-
 5 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6d95f49..73d1139 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2021-01-02  Bruno Haible  <[email protected]>
 
+	utimens: Avoid test failures on macOS 10.13.
+	Reported by Martin Storsjö <[email protected]> in
+	<https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.
+	* tests/test-utimens-common.h (check_ctime): Define to -1 on macOS.
+	* tests/test-utimens.h (test_utimens): Don't expect a ctime change when
+	only the atime is requested to change.
+	* tests/test-futimens.h (test_futimens): Likewise.
+	* tests/test-lutimens.h (test_lutimens): Likewise.
+
+2021-01-02  Bruno Haible  <[email protected]>
+
 	renameatu: Fix test failures on macOS.
 	Reported by Martin Storsjö <[email protected]> in
 	<https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.
diff --git a/tests/test-futimens.h b/tests/test-futimens.h
index 6a17013..31ff900 100644
--- a/tests/test-futimens.h
+++ b/tests/test-futimens.h
@@ -166,7 +166,7 @@ test_futimens (int (*func) (int, struct timespec const *),
     ASSERT (get_stat_atime_ns (&st2) == 0);
     ASSERT (st3.st_mtime == st2.st_mtime);
     ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
-    if (check_ctime)
+    if (check_ctime > 0)
       ASSERT (ctime_compare (&st3, &st2) < 0);
   }
 
diff --git a/tests/test-lutimens.h b/tests/test-lutimens.h
index f6d5586..589c9cf 100644
--- a/tests/test-lutimens.h
+++ b/tests/test-lutimens.h
@@ -194,7 +194,7 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
       }
     ASSERT (st3.st_mtime == st2.st_mtime);
     ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
-    if (check_ctime)
+    if (check_ctime > 0)
       ASSERT (ctime_compare (&st3, &st2) < 0);
   }
 
diff --git a/tests/test-utimens-common.h b/tests/test-utimens-common.h
index 5861667..3d665ef 100644
--- a/tests/test-utimens-common.h
+++ b/tests/test-utimens-common.h
@@ -55,6 +55,9 @@ enum {
    properly tracked change time.  See
    <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions>.  */
 #  define check_ctime 0
+# elif defined __APPLE__ && defined __MACH__
+/* On macOS, the ctime is not updated when only the st_atime changes.  */
+#  define check_ctime -1
 # else
 #  define check_ctime 1
 # endif
diff --git a/tests/test-utimens.h b/tests/test-utimens.h
index c3c7029..9273fd0 100644
--- a/tests/test-utimens.h
+++ b/tests/test-utimens.h
@@ -145,7 +145,7 @@ test_utimens (int (*func) (char const *, struct timespec const *), bool print)
     ASSERT (get_stat_atime_ns (&st2) == 0);
     ASSERT (st3.st_mtime == st2.st_mtime);
     ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
-    if (check_ctime)
+    if (check_ctime > 0)
       ASSERT (ctime_compare (&st3, &st2) < 0);
   }
 
-- 
2.7.4

From 86c8ff740b64f3724de20d71dca481bef30b18dd Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sat, 2 Jan 2021 18:59:12 +0100
Subject: [PATCH 2/2] utimens: Fix test failure on macOS 10.13.

* lib/utimens.c (fdutimens): Before calling utimensat, recognize a
filename ending in a slash that does not point to a directory.
---
 ChangeLog     |  6 ++++++
 lib/utimens.c | 14 ++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 73d1139..5087bf4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2021-01-02  Bruno Haible  <[email protected]>
 
+	utimens: Fix test failure on macOS 10.13.
+	* lib/utimens.c (fdutimens): Before calling utimensat, recognize a
+	filename ending in a slash that does not point to a directory.
+
+2021-01-02  Bruno Haible  <[email protected]>
+
 	utimens: Avoid test failures on macOS 10.13.
 	Reported by Martin Storsjö <[email protected]> in
 	<https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.
diff --git a/lib/utimens.c b/lib/utimens.c
index 5bbae05..9f9c30a 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -246,6 +246,20 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
 # if HAVE_UTIMENSAT
       if (fd < 0)
         {
+#  if defined __APPLE__ && defined __MACH__
+          size_t len = strlen (file);
+          if (len > 0 && file[len - 1] == '/')
+            {
+              struct stat statbuf;
+              if (stat (file, &statbuf) < 0)
+                return -1;
+              if (!S_ISDIR (statbuf.st_mode))
+                {
+                  errno = ENOTDIR;
+                  return -1;
+                }
+            }
+#  endif
           result = utimensat (AT_FDCWD, file, ts, 0);
 #  ifdef __linux__
           /* Work around a kernel bug:
-- 
2.7.4

Reply via email to