nsec: support NDK's crazy nanoseconds Android NDK does not have a `struct timespec` in its `struct stat` for nanosecond support, instead it has a single nanosecond member inside the struct stat itself. We will use that and use a macro to expand to the `st_mtim` / `st_mtimespec` definition on other systems (much like the existing `st_mtime` backcompat definition).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0aa5862..6a7dac2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,17 +86,21 @@ IF (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
OPTION( USE_OPENSSL "Link with and use openssl library" ON )
ENDIF()
-CHECK_STRUCT_HAS_MEMBER ("struct stat" st_atim "sys/types.h;sys/stat.h"
- HAVE_STRUCT_STAT_ST_ATIM LANGUAGE C)
-CHECK_STRUCT_HAS_MEMBER ("struct stat" st_atimespec "sys/types.h;sys/stat.h"
- HAVE_STRUCT_STAT_ST_ATIMESPEC LANGUAGE C)
-
-IF (HAVE_STRUCT_STAT_ST_ATIM)
+CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtim "sys/types.h;sys/stat.h"
+ HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
+CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtimespec "sys/types.h;sys/stat.h"
+ HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C)
+CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_nsec sys/stat.h
+ HAVE_STRUCT_STAT_MTIME_NSEC LANGUAGE C)
+
+IF (HAVE_STRUCT_STAT_ST_MTIM)
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
-ELSEIF (HAVE_STRUCT_STAT_ST_ATIMESPEC)
+ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
+ELSE ()
+ SET( HAVE_STRUCT_STAT_NSEC ON )
ENDIF()
IF (HAVE_STRUCT_STAT_NSEC OR WIN32)
@@ -539,8 +543,12 @@ IF (USE_NSEC)
ADD_DEFINITIONS(-DGIT_USE_NSEC)
ENDIF()
-IF (HAVE_STRUCT_STAT_ST_ATIMESPEC)
- ADD_DEFINITIONS(-DGIT_USE_STAT_ATIMESPEC)
+IF (HAVE_STRUCT_STAT_ST_MTIM)
+ ADD_DEFINITIONS(-DGIT_USE_STAT_MTIM)
+ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
+ ADD_DEFINITIONS(-DGIT_USE_STAT_MTIMESPEC)
+ELSEIF (HAVE_STRUCT_STAT_ST_MTIME_NSEC)
+ ADD_DEFINITIONS(-DGIT_USE_STAT_MTIME_NSEC)
ENDIF()
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
diff --git a/src/fileops.c b/src/fileops.c
index 150333d..22868b4 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -1034,7 +1034,6 @@ int git_futils_filestamp_check(
git_futils_filestamp *stamp, const char *path)
{
struct stat st;
- const struct timespec *statmtime = &st.st_mtim;
/* if the stamp is NULL, then always reload */
if (stamp == NULL)
@@ -1043,17 +1042,17 @@ int git_futils_filestamp_check(
if (p_stat(path, &st) < 0)
return GIT_ENOTFOUND;
- if (stamp->mtime.tv_sec == statmtime->tv_sec &&
+ if (stamp->mtime.tv_sec == st.st_mtime &&
#if defined(GIT_USE_NSEC)
- stamp->mtime.tv_nsec == statmtime->tv_nsec &&
+ stamp->mtime.tv_nsec == st.st_mtime_nsec &&
#endif
stamp->size == (git_off_t)st.st_size &&
stamp->ino == (unsigned int)st.st_ino)
return 0;
- stamp->mtime.tv_sec = statmtime->tv_sec;
+ stamp->mtime.tv_sec = st.st_mtime;
#if defined(GIT_USE_NSEC)
- stamp->mtime.tv_nsec = statmtime->tv_nsec;
+ stamp->mtime.tv_nsec = st.st_mtime_nsec;
#endif
stamp->size = (git_off_t)st.st_size;
stamp->ino = (unsigned int)st.st_ino;
@@ -1076,11 +1075,11 @@ void git_futils_filestamp_set(
void git_futils_filestamp_set_from_stat(
git_futils_filestamp *stamp, struct stat *st)
{
- const struct timespec *statmtime = &st->st_mtim;
-
if (st) {
- stamp->mtime = *statmtime;
-#if !defined(GIT_USE_NSEC)
+ stamp->mtime.tv_sec = st->st_mtime;
+#if defined(GIT_USE_NSEC)
+ stamp->mtime.tv_nsec = st->st_mtime_nsec;
+#else
stamp->mtime.tv_nsec = 0;
#endif
stamp->size = (git_off_t)st->st_size;
diff --git a/src/index.c b/src/index.c
index d0a0da2..c18f358 100644
--- a/src/index.c
+++ b/src/index.c
@@ -829,8 +829,8 @@ void git_index_entry__init_from_stat(
entry->ctime.seconds = (int32_t)st->st_ctime;
entry->mtime.seconds = (int32_t)st->st_mtime;
#if defined(GIT_USE_NSEC)
- entry->mtime.nanoseconds = st->st_mtim.tv_nsec;
- entry->ctime.nanoseconds = st->st_ctim.tv_nsec;
+ entry->mtime.nanoseconds = st->st_mtime_nsec;
+ entry->ctime.nanoseconds = st->st_ctime_nsec;
#endif
entry->dev = st->st_rdev;
entry->ino = st->st_ino;
diff --git a/src/unix/posix.h b/src/unix/posix.h
index 83edf2b..482d2c8 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -21,6 +21,18 @@ typedef int GIT_SOCKET;
#define p_lstat(p,b) lstat(p,b)
#define p_stat(p,b) stat(p, b)
+#if defined(GIT_USE_STAT_MTIMESPEC)
+# define st_atime_nsec st_atimespec.tv_nsec
+# define st_mtime_nsec st_mtimespec.tv_nsec
+# define st_ctime_nsec st_ctimespec.tv_nsec
+#elif defined(GIT_USE_STAT_MTIM)
+# define st_atime_nsec st_atim.tv_nsec
+# define st_mtime_nsec st_mtim.tv_nsec
+# define st_ctime_nsec st_ctim.tv_nsec
+#elif !defined(GIT_USE_STAT_MTIME_NSEC) && defined(GIT_USE_NEC)
+# error GIT_USE_NSEC defined but unknown struct stat nanosecond type
+#endif
+
#define p_utimes(f, t) utimes(f, t)
#define p_readlink(a, b, c) readlink(a, b, c)
diff --git a/src/win32/win32-compat.h b/src/win32/win32-compat.h
index dff1f45..f888fd6 100644
--- a/src/win32/win32-compat.h
+++ b/src/win32/win32-compat.h
@@ -42,6 +42,9 @@ struct p_stat {
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
+#define st_atime_nsec st_atim.tv_nsec
+#define st_mtime_nsec st_mtim.tv_nsec
+#define st_ctime_nsec st_ctim.tv_nsec
};
#define stat p_stat