summaryrefslogtreecommitdiff
path: root/compat/mingw.c
diff options
context:
space:
mode:
authorKarsten Blees <blees@dcon.de>2018-10-23 10:23:22 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-10-24 04:18:14 (GMT)
commitd7e8c87421868ab7dab2814360d277a425b42bc5 (patch)
treef4c6b73fac6102498c3758c7e20424b387de0c2b /compat/mingw.c
parentd75e6973539f1f99561ae6f42a81f024497e3dfa (diff)
downloadgit-d7e8c87421868ab7dab2814360d277a425b42bc5.zip
git-d7e8c87421868ab7dab2814360d277a425b42bc5.tar.gz
git-d7e8c87421868ab7dab2814360d277a425b42bc5.tar.bz2
mingw: implement nanosecond-precision file times
We no longer use any of MSVCRT's stat-functions, so there's no need to stick to a CRT-compatible 'struct stat' either. Define and use our own POSIX-2013-compatible 'struct stat' with nanosecond- precision file times. Note: This can cause performance issues when using Git variants with different file time resolutions, as the timestamps are stored in the Git index: after updating the index with a Git variant that uses second-precision file times, a nanosecond-aware Git will think that pretty much every single file listed in the index is out of date. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat/mingw.c')
-rw-r--r--compat/mingw.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 07fc0b7..26016d0 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -592,9 +592,11 @@ static inline long long filetime_to_hnsec(const FILETIME *ft)
return winTime - 116444736000000000LL;
}
-static inline time_t filetime_to_time_t(const FILETIME *ft)
+static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
{
- return (time_t)(filetime_to_hnsec(ft) / 10000000);
+ long long hnsec = filetime_to_hnsec(ft);
+ ts->tv_sec = (time_t)(hnsec / 10000000);
+ ts->tv_nsec = (hnsec % 10000000) * 100;
}
/**
@@ -653,9 +655,9 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
buf->st_size = fdata.nFileSizeLow |
(((off_t)fdata.nFileSizeHigh)<<32);
buf->st_dev = buf->st_rdev = 0; /* not used by Git */
- buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
- buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
- buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
+ filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
+ filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
+ filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
WIN32_FIND_DATAW findbuf;
HANDLE handle = FindFirstFileW(wfilename, &findbuf);
@@ -753,9 +755,9 @@ static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
buf->st_size = fdata.nFileSizeLow |
(((off_t)fdata.nFileSizeHigh)<<32);
buf->st_dev = buf->st_rdev = 0; /* not used by Git */
- buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
- buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
- buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
+ filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
+ filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
+ filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
return 0;
}