>From e678d85fb0ebb5c9c139f223c628e01d163a0cd0 Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Thu, 18 Jul 2019 17:43:28 -0700
Subject: [PATCH] utimensat: work around macOS utimensat bug

Problem reported by Max Jonas Werner in:
https://lists.gnu.org/r/bug-gnulib/2019-07/msg00067.html
* m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Also check for UTIME_OMIT
resetting timestamp to zero.  Assume the bug occurs on macOS
when cross-compiling.
---
 ChangeLog       |  9 +++++++++
 lib/utimensat.c |  7 ++++++-
 m4/utimensat.m4 | 23 +++++++++++++++++++----
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 08bcf1082..6b455de7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2019-07-18  Paul Eggert  <address@hidden>
+
+	utimensat: work around macOS utimensat bug
+	Problem reported by Max Jonas Werner in:
+	https://lists.gnu.org/r/bug-gnulib/2019-07/msg00067.html
+	* m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Also check for UTIME_OMIT
+	resetting timestamp to zero.  Assume the bug occurs on macOS
+	when cross-compiling.
+
 2019-07-16  Bruno Haible  <address@hidden>
 
 	update-copyright: Make it work again (regression from 2019-06-15).
diff --git a/lib/utimensat.c b/lib/utimensat.c
index ebd339d90..4f472e795 100644
--- a/lib/utimensat.c
+++ b/lib/utimensat.c
@@ -71,7 +71,12 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
 
          The same bug occurs in Solaris 11.1 (Apr 2013).
 
-         FIXME: Simplify this in 2024, when these file system bugs are
+         A different bug occurs in macOS 10.14.5 (2019), which
+         treats UTIME_OMIT as if it specified time_t 0.  See:
+         https://github.com/rfjakob/gocryptfs/issues/229
+         https://lists.gnu.org/r/bug-gnulib/2019-07/msg00067.html
+
+         FIXME: Simplify this in 2029, when these file system bugs are
          no longer common on Gnulib target platforms.  */
       if (times && (times[0].tv_nsec == UTIME_OMIT
                     || times[1].tv_nsec == UTIME_OMIT))
diff --git a/m4/utimensat.m4 b/m4/utimensat.m4
index 5628f8efe..065f03c18 100644
--- a/m4/utimensat.m4
+++ b/m4/utimensat.m4
@@ -1,4 +1,4 @@
-# serial 6
+# serial 7
 # See if we need to provide utimensat replacement.
 
 dnl Copyright (C) 2009-2019 Free Software Foundation, Inc.
@@ -56,13 +56,28 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
                   result |= 16;
                 else if (st.st_ctime < st.st_atime)
                   result |= 32;
+                else if (st.st_mtime <= 0)
+                  result |= 64;
               }
               return result;
             ]])],
-         [gl_cv_func_utimensat_works=yes],
+dnl FIXME: Simplify this in 2029, when these file system bugs are no
+dnl longer common.
+         [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if defined __APPLE__ && defined __MACH__
+/* macOS added utimensat in xnu-4570.1.46 (released 2017), but it
+   mishandles UTIME_OMIT; see:
+     https://github.com/rfjakob/gocryptfs/issues/229
+     https://lists.gnu.org/r/bug-gnulib/2019-07/msg00067.html
+   For now, always replace utimensat on macOS.  */
+choke me
+#endif
+      ]])],
+           [gl_cv_func_utimensat_works=yes],
+           [gl_cv_func_utimensat_works="needs runtime check"])],
          [gl_cv_func_utimensat_works=no],
-         [gl_cv_func_utimensat_works="guessing yes"])])
-    if test "$gl_cv_func_utimensat_works" = no; then
+         [gl_cv_func_utimensat_works="guessing no"])])
+    if test "$gl_cv_func_utimensat_works" != yes; then
       REPLACE_UTIMENSAT=1
     fi
   fi
-- 
2.17.1