diff options
| author | Eli Zaretskii | 2025-05-11 13:33:24 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2025-05-11 13:33:24 +0300 |
| commit | 3975094f1d96680fe73232ca4216733904ebecd0 (patch) | |
| tree | 9944f35bd730451694fc81960c71581ed3416550 /lib-src | |
| parent | 9df2074a06fefa0b5bfe9714b45c383fa45d6650 (diff) | |
| download | emacs-3975094f1d96680fe73232ca4216733904ebecd0.tar.gz emacs-3975094f1d96680fe73232ca4216733904ebecd0.zip | |
Support sub-second file time-stamps on MS-Windows
* nt/inc/sys/stat.h (struct stat): New members for nsec part of
file times.
* lib-src/ntlib.c (convert_time):
* src/w32.c (convert_time): Accept an additional argument
TIME_NSEC and set it to the sub-second part of time. All callers
changed.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ntlib.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index bcb9a4bbab2..2ba8d09c1ec 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c | |||
| @@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 30 | #include <direct.h> | 30 | #include <direct.h> |
| 31 | #include <sys/types.h> | 31 | #include <sys/types.h> |
| 32 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
| 33 | #include <math.h> | ||
| 33 | #include <errno.h> | 34 | #include <errno.h> |
| 34 | #include <ctype.h> | 35 | #include <ctype.h> |
| 35 | #include <sys/timeb.h> | 36 | #include <sys/timeb.h> |
| @@ -256,7 +257,7 @@ static long double utc_base; | |||
| 256 | static int init = 0; | 257 | static int init = 0; |
| 257 | 258 | ||
| 258 | static time_t | 259 | static time_t |
| 259 | convert_time (FILETIME ft) | 260 | convert_time (FILETIME ft, int *time_nsec) |
| 260 | { | 261 | { |
| 261 | long double ret; | 262 | long double ret; |
| 262 | 263 | ||
| @@ -266,7 +267,8 @@ convert_time (FILETIME ft) | |||
| 266 | ret = (long double) ft.dwHighDateTime | 267 | ret = (long double) ft.dwHighDateTime |
| 267 | * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime; | 268 | * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime; |
| 268 | ret -= utc_base; | 269 | ret -= utc_base; |
| 269 | return (time_t) (ret * 1e-7L); | 270 | *time_nsec = (int) fmodl (ret, 1.0e7L) * 100; |
| 271 | return (time_t) (ret * 1.0e-7L); | ||
| 270 | } | 272 | } |
| 271 | 273 | ||
| 272 | static int | 274 | static int |
| @@ -373,11 +375,19 @@ stat (const char * path, struct stat * buf) | |||
| 373 | buf->st_size += wfd.nFileSizeLow; | 375 | buf->st_size += wfd.nFileSizeLow; |
| 374 | 376 | ||
| 375 | /* Convert timestamps to Unix format. */ | 377 | /* Convert timestamps to Unix format. */ |
| 376 | buf->st_mtime = convert_time (wfd.ftLastWriteTime); | 378 | buf->st_mtime = convert_time (wfd.ftLastWriteTime, &buf->st_mtimensec); |
| 377 | buf->st_atime = convert_time (wfd.ftLastAccessTime); | 379 | buf->st_atime = convert_time (wfd.ftLastAccessTime, &buf->st_atimensec); |
| 378 | if (buf->st_atime == 0) buf->st_atime = buf->st_mtime; | 380 | if (buf->st_atime == 0) |
| 379 | buf->st_ctime = convert_time (wfd.ftCreationTime); | 381 | { |
| 380 | if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime; | 382 | buf->st_atime = buf->st_mtime; |
| 383 | buf->st_atimensec = buf->st_mtimensec; | ||
| 384 | } | ||
| 385 | buf->st_ctime = convert_time (wfd.ftCreationTime, &buf->st_ctimensec); | ||
| 386 | if (buf->st_ctime == 0) | ||
| 387 | { | ||
| 388 | buf->st_ctime = buf->st_mtime; | ||
| 389 | buf->st_ctimensec = buf->st_mtimensec; | ||
| 390 | } | ||
| 381 | 391 | ||
| 382 | /* determine rwx permissions */ | 392 | /* determine rwx permissions */ |
| 383 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) | 393 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) |
| @@ -473,11 +483,19 @@ fstat (int desc, struct stat * buf) | |||
| 473 | buf->st_size += info.nFileSizeLow; | 483 | buf->st_size += info.nFileSizeLow; |
| 474 | 484 | ||
| 475 | /* Convert timestamps to Unix format. */ | 485 | /* Convert timestamps to Unix format. */ |
| 476 | buf->st_mtime = convert_time (info.ftLastWriteTime); | 486 | buf->st_mtime = convert_time (info.ftLastWriteTime, &buf->st_mtimensec); |
| 477 | buf->st_atime = convert_time (info.ftLastAccessTime); | 487 | buf->st_atime = convert_time (info.ftLastAccessTime, &buf->st_atimensec); |
| 478 | if (buf->st_atime == 0) buf->st_atime = buf->st_mtime; | 488 | if (buf->st_atime == 0) |
| 479 | buf->st_ctime = convert_time (info.ftCreationTime); | 489 | { |
| 480 | if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime; | 490 | buf->st_atime = buf->st_mtime; |
| 491 | buf->st_atimensec = buf->st_mtimensec; | ||
| 492 | } | ||
| 493 | buf->st_ctime = convert_time (info.ftCreationTime, &buf->st_ctimensec); | ||
| 494 | if (buf->st_ctime == 0) | ||
| 495 | { | ||
| 496 | buf->st_ctime = buf->st_mtime; | ||
| 497 | buf->st_ctimensec = buf->st_mtimensec; | ||
| 498 | } | ||
| 481 | 499 | ||
| 482 | /* determine rwx permissions */ | 500 | /* determine rwx permissions */ |
| 483 | if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) | 501 | if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) |