From ed82989c0640d8ae341cc16a9c8e89586f5cee66 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Tue, 6 Oct 2015 08:51:21 -0400
Subject: [PATCH] SystemTools: Implement nanosecond file times on OS X

Teach the Touch and FileTimeCompare methods to use the `st_mtimespec`
member of `struct stat` on OS X.

Change-Id: Ib7dcca41eee571af23509536fe4768a68d98a81a
---
 CMakeLists.txt            |  3 +++
 SystemTools.cxx           | 21 +++++++++++++++++++++
 kwsysPlatformTestsCXX.cxx | 13 +++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 869ae29..ce7f563 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -508,6 +508,8 @@ IF(KWSYS_USE_SystemTools)
     "Checking whether CXX compiler has utimensat" DIRECT)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIM
     "Checking whether CXX compiler struct stat has st_mtim member" DIRECT)
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+    "Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT)
   SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
     KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
     KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
@@ -515,6 +517,7 @@ IF(KWSYS_USE_SystemTools)
     KWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES}
     KWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT}
     KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
+    KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
     )
 ENDIF()
 
diff --git a/SystemTools.cxx b/SystemTools.cxx
index cea6a10..da34eb9 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -1370,6 +1370,9 @@ bool SystemTools::Touch(const std::string& filename, bool create)
 #  if KWSYS_CXX_STAT_HAS_ST_MTIM
   atime.tv_sec = st.st_atim.tv_sec;
   atime.tv_usec = st.st_atim.tv_nsec/1000;
+#  elif KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+  atime.tv_sec = st.st_atimespec.tv_sec;
+  atime.tv_usec = st.st_atimespec.tv_nsec/1000;
 #  else
   atime.tv_sec = st.st_atime;
   atime.tv_usec = 0;
@@ -1426,6 +1429,24 @@ bool SystemTools::FileTimeCompare(const std::string& f1,
     {
     *result = 1;
     }
+# elif KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+  // Compare using nanosecond resolution.
+  if(s1.st_mtimespec.tv_sec < s2.st_mtimespec.tv_sec)
+    {
+    *result = -1;
+    }
+  else if(s1.st_mtimespec.tv_sec > s2.st_mtimespec.tv_sec)
+    {
+    *result = 1;
+    }
+  else if(s1.st_mtimespec.tv_nsec < s2.st_mtimespec.tv_nsec)
+    {
+    *result = -1;
+    }
+  else if(s1.st_mtimespec.tv_nsec > s2.st_mtimespec.tv_nsec)
+    {
+    *result = 1;
+    }
 # else
   // Compare using 1 second resolution.
   if(s1.st_mtime < s2.st_mtime)
diff --git a/kwsysPlatformTestsCXX.cxx b/kwsysPlatformTestsCXX.cxx
index ab5ae64..9626937 100644
--- a/kwsysPlatformTestsCXX.cxx
+++ b/kwsysPlatformTestsCXX.cxx
@@ -45,6 +45,19 @@ int main()
 }
 #endif
 
+#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+int main()
+{
+  struct stat stat1;
+  (void)stat1.st_mtimespec.tv_sec;
+  (void)stat1.st_mtimespec.tv_nsec;
+  return 0;
+}
+#endif
+
 #ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
 void function(long**) {}
 int main()
-- 
GitLab