aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorEli Zaretskii2025-05-11 13:33:24 +0300
committerEli Zaretskii2025-05-11 13:33:24 +0300
commit3975094f1d96680fe73232ca4216733904ebecd0 (patch)
tree9944f35bd730451694fc81960c71581ed3416550 /lib-src
parent9df2074a06fefa0b5bfe9714b45c383fa45d6650 (diff)
downloademacs-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.c42
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;
256static int init = 0; 257static int init = 0;
257 258
258static time_t 259static time_t
259convert_time (FILETIME ft) 260convert_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
272static int 274static 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)