From 399e2c814019dfeeec45f2de0ecbb0893ebb5126 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Sat, 30 Apr 2016 16:56:56 -0700 Subject: [PATCH] win: support sub-second precision in uv_fs_futimes() Fixes: https://github.com/libuv/libuv/issues/800 PR-URL: https://github.com/libuv/libuv/pull/849 Reviewed-by: Bert Belder --- docs/src/fs.rst | 2 ++ src/win/fs.c | 6 +++--- test/test-fs.c | 22 ++++++++++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/src/fs.rst b/docs/src/fs.rst index 69e283f4..918bff94 100644 --- a/docs/src/fs.rst +++ b/docs/src/fs.rst @@ -258,6 +258,8 @@ API Equivalent to :man:`utime(2)` and :man:`futime(2)` respectively. + .. versionchanged:: 1.10.0 sub-second precission is supported on Windows + .. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) Equivalent to :man:`link(2)`. diff --git a/src/win/fs.c b/src/win/fs.c index 54dfea72..24c60847 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -94,7 +94,7 @@ #define TIME_T_TO_FILETIME(time, filetime_ptr) \ do { \ - uint64_t bigtime = ((int64_t) (time) * 10000000LL) + \ + uint64_t bigtime = ((uint64_t) ((time) * 10000000ULL)) + \ 116444736000000000ULL; \ (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \ (filetime_ptr)->dwHighDateTime = bigtime >> 32; \ @@ -1429,8 +1429,8 @@ static void fs__fchmod(uv_fs_t* req) { INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) { FILETIME filetime_a, filetime_m; - TIME_T_TO_FILETIME((time_t) atime, &filetime_a); - TIME_T_TO_FILETIME((time_t) mtime, &filetime_m); + TIME_T_TO_FILETIME(atime, &filetime_a); + TIME_T_TO_FILETIME(mtime, &filetime_m); if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) { return -1; diff --git a/test/test-fs.c b/test/test-fs.c index 1cc1a7c0..250d1350 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -662,8 +662,8 @@ static void check_utime(const char* path, double atime, double mtime) { ASSERT(req.result == 0); s = &req.statbuf; - ASSERT(s->st_atim.tv_sec == atime); - ASSERT(s->st_mtim.tv_sec == mtime); + ASSERT(s->st_atim.tv_sec + (s->st_atim.tv_nsec / 1000000000.0) == atime); + ASSERT(s->st_mtim.tv_sec + (s->st_mtim.tv_nsec / 1000000000.0) == mtime); uv_fs_req_cleanup(&req); } @@ -1968,6 +1968,15 @@ TEST_IMPL(fs_utime) { atime = mtime = 400497753; /* 1982-09-10 11:22:33 */ + /* + * Test sub-second timestamps only on Windows (assuming NTFS). Some other + * platforms support sub-second timestamps, but that support is filesystem- + * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps. + */ +#ifdef _WIN32 + mtime += 0.444; /* 1982-09-10 11:22:33.444 */ +#endif + r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL); ASSERT(r == 0); ASSERT(req.result == 0); @@ -2055,6 +2064,15 @@ TEST_IMPL(fs_futime) { atime = mtime = 400497753; /* 1982-09-10 11:22:33 */ + /* + * Test sub-second timestamps only on Windows (assuming NTFS). Some other + * platforms support sub-second timestamps, but that support is filesystem- + * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps. + */ +#ifdef _WIN32 + mtime += 0.444; /* 1982-09-10 11:22:33.444 */ +#endif + r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL); ASSERT(r >= 0); ASSERT(req.result >= 0);