Merge pull request #3638 from ethomson/nsec USE_NSECS fixes
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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
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 483f7af..5704432 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
diff --git a/tests/index/nsec.c b/tests/index/nsec.c
index 5004339..244ab63 100644
--- a/tests/index/nsec.c
+++ b/tests/index/nsec.c
@@ -61,8 +61,17 @@ void test_index_nsec__staging_maintains_other_nanos(void)
cl_assert_equal_b(true, has_nsecs());
cl_assert((entry = git_index_get_bypath(repo_index, "a.txt", 0)));
+
+ /* if we are writing nanoseconds to the index, expect them to be
+ * nonzero. if we are *not*, expect that we truncated the entry.
+ */
+#ifdef GIT_USE_NSEC
+ cl_assert(entry->ctime.nanoseconds != 0);
+ cl_assert(entry->mtime.nanoseconds != 0);
+#else
cl_assert_equal_i(0, entry->ctime.nanoseconds);
cl_assert_equal_i(0, entry->mtime.nanoseconds);
+#endif
}
void test_index_nsec__status_doesnt_clear_nsecs(void)