diff options
author | Ron Yorston <rmy@pobox.com> | 2019-08-16 09:33:29 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-08-16 09:33:29 +0100 |
commit | ae65dc37bcc9b1d9cef0b111131c79dc4ba1bf51 (patch) | |
tree | 91cec33a60c2fc7fc90bd9bbd587b65eaf0e55d2 /win32 | |
parent | 01950ee1937fdb5172673afad5b65bdb48fe89de (diff) | |
download | busybox-w32-ae65dc37bcc9b1d9cef0b111131c79dc4ba1bf51.tar.gz busybox-w32-ae65dc37bcc9b1d9cef0b111131c79dc4ba1bf51.tar.bz2 busybox-w32-ae65dc37bcc9b1d9cef0b111131c79dc4ba1bf51.zip |
win32: allow nanosecond precision in file times
Modern Linux kernels use struct timespec to represent file times,
thus allowing nanosecond precision. Update the WIN32 emulation of
struct stat and stat(2) to do the same.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 3f80b53f1..7e4d6a318 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -277,6 +277,17 @@ static inline time_t filetime_to_time_t(const FILETIME *ft) | |||
277 | return (time_t)(filetime_to_hnsec(ft) / 10000000); | 277 | return (time_t)(filetime_to_hnsec(ft) / 10000000); |
278 | } | 278 | } |
279 | 279 | ||
280 | static inline struct timespec filetime_to_timespec(const FILETIME *ft) | ||
281 | { | ||
282 | struct timespec ts; | ||
283 | long long winTime = filetime_to_hnsec(ft); | ||
284 | |||
285 | ts.tv_sec = (time_t)(winTime / 10000000); | ||
286 | ts.tv_nsec = (long)(winTime % 10000000) * 100; | ||
287 | |||
288 | return ts; | ||
289 | } | ||
290 | |||
280 | static inline mode_t file_attr_to_st_mode(DWORD attr) | 291 | static inline mode_t file_attr_to_st_mode(DWORD attr) |
281 | { | 292 | { |
282 | mode_t fMode = S_IRUSR|S_IRGRP|S_IROTH; | 293 | mode_t fMode = S_IRUSR|S_IRGRP|S_IROTH; |
@@ -530,9 +541,9 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
530 | /* Get the contents of a symlink, not its target. */ | 541 | /* Get the contents of a symlink, not its target. */ |
531 | buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; | 542 | buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; |
532 | buf->st_size = name ? strlen(name) : 0; /* should use readlink */ | 543 | buf->st_size = name ? strlen(name) : 0; /* should use readlink */ |
533 | buf->st_atime = filetime_to_time_t(&(findbuf.ftLastAccessTime)); | 544 | buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime)); |
534 | buf->st_mtime = filetime_to_time_t(&(findbuf.ftLastWriteTime)); | 545 | buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime)); |
535 | buf->st_ctime = filetime_to_time_t(&(findbuf.ftCreationTime)); | 546 | buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime)); |
536 | } | 547 | } |
537 | else { | 548 | else { |
538 | /* The file is not a symlink. */ | 549 | /* The file is not a symlink. */ |
@@ -542,9 +553,9 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
542 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; | 553 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; |
543 | buf->st_size = fdata.nFileSizeLow | | 554 | buf->st_size = fdata.nFileSizeLow | |
544 | (((off64_t)fdata.nFileSizeHigh)<<32); | 555 | (((off64_t)fdata.nFileSizeHigh)<<32); |
545 | buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); | 556 | buf->st_atim = filetime_to_timespec(&(fdata.ftLastAccessTime)); |
546 | buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); | 557 | buf->st_mtim = filetime_to_timespec(&(fdata.ftLastWriteTime)); |
547 | buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); | 558 | buf->st_ctim = filetime_to_timespec(&(fdata.ftCreationTime)); |
548 | } | 559 | } |
549 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : 1; | 560 | buf->st_nlink = S_ISDIR(buf->st_mode) ? 2 : 1; |
550 | 561 | ||
@@ -594,6 +605,9 @@ int mingw_stat(const char *file_name, struct mingw_stat *buf) | |||
594 | return do_lstat(1, file_name, buf); | 605 | return do_lstat(1, file_name, buf); |
595 | } | 606 | } |
596 | 607 | ||
608 | #undef st_atime | ||
609 | #undef st_mtime | ||
610 | #undef st_ctime | ||
597 | int mingw_fstat(int fd, struct mingw_stat *buf) | 611 | int mingw_fstat(int fd, struct mingw_stat *buf) |
598 | { | 612 | { |
599 | HANDLE fh = (HANDLE)_get_osfhandle(fd); | 613 | HANDLE fh = (HANDLE)_get_osfhandle(fd); |
@@ -612,9 +626,12 @@ int mingw_fstat(int fd, struct mingw_stat *buf) | |||
612 | } | 626 | } |
613 | buf->st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; | 627 | buf->st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; |
614 | buf->st_size = buf64.st_size; | 628 | buf->st_size = buf64.st_size; |
615 | buf->st_atime = buf64.st_atime; | 629 | buf->st_atim.tv_sec = buf64.st_atime; |
616 | buf->st_mtime = buf64.st_mtime; | 630 | buf->st_atim.tv_nsec = 0; |
617 | buf->st_ctime = buf64.st_ctime; | 631 | buf->st_mtim.tv_sec = buf64.st_mtime; |
632 | buf->st_mtim.tv_nsec = 0; | ||
633 | buf->st_ctim.tv_sec = buf64.st_ctime; | ||
634 | buf->st_ctim.tv_nsec = 0; | ||
618 | buf->st_blocks = ((buf64.st_size+4095)>>12)<<3; | 635 | buf->st_blocks = ((buf64.st_size+4095)>>12)<<3; |
619 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | 636 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
620 | buf->st_dev = 0; | 637 | buf->st_dev = 0; |
@@ -628,9 +645,9 @@ int mingw_fstat(int fd, struct mingw_stat *buf) | |||
628 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); | 645 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); |
629 | buf->st_size = fdata.nFileSizeLow | | 646 | buf->st_size = fdata.nFileSizeLow | |
630 | (((off64_t)fdata.nFileSizeHigh)<<32); | 647 | (((off64_t)fdata.nFileSizeHigh)<<32); |
631 | buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); | 648 | buf->st_atim = filetime_to_timespec(&(fdata.ftLastAccessTime)); |
632 | buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); | 649 | buf->st_mtim = filetime_to_timespec(&(fdata.ftLastWriteTime)); |
633 | buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); | 650 | buf->st_ctim = filetime_to_timespec(&(fdata.ftCreationTime)); |
634 | buf->st_blocks = ((buf->st_size+4095)>>12)<<3; | 651 | buf->st_blocks = ((buf->st_size+4095)>>12)<<3; |
635 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | 652 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
636 | buf->st_dev = fdata.dwVolumeSerialNumber; | 653 | buf->st_dev = fdata.dwVolumeSerialNumber; |