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 . */
#include
#include
#include
+#include
#include
#include
#include
@@ -256,7 +257,7 @@ static long double utc_base;
static int init = 0;
static time_t
-convert_time (FILETIME ft)
+convert_time (FILETIME ft, int *time_nsec)
{
long double ret;
@@ -266,7 +267,8 @@ convert_time (FILETIME ft)
ret = (long double) ft.dwHighDateTime
* 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
ret -= utc_base;
- return (time_t) (ret * 1e-7L);
+ *time_nsec = (int) fmodl (ret, 1.0e7L) * 100;
+ return (time_t) (ret * 1.0e-7L);
}
static int
@@ -373,11 +375,19 @@ stat (const char * path, struct stat * buf)
buf->st_size += wfd.nFileSizeLow;
/* Convert timestamps to Unix format. */
- buf->st_mtime = convert_time (wfd.ftLastWriteTime);
- buf->st_atime = convert_time (wfd.ftLastAccessTime);
- if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
- buf->st_ctime = convert_time (wfd.ftCreationTime);
- if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+ buf->st_mtime = convert_time (wfd.ftLastWriteTime, &buf->st_mtimensec);
+ buf->st_atime = convert_time (wfd.ftLastAccessTime, &buf->st_atimensec);
+ if (buf->st_atime == 0)
+ {
+ buf->st_atime = buf->st_mtime;
+ buf->st_atimensec = buf->st_mtimensec;
+ }
+ buf->st_ctime = convert_time (wfd.ftCreationTime, &buf->st_ctimensec);
+ if (buf->st_ctime == 0)
+ {
+ buf->st_ctime = buf->st_mtime;
+ buf->st_ctimensec = buf->st_mtimensec;
+ }
/* determine rwx permissions */
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
@@ -473,11 +483,19 @@ fstat (int desc, struct stat * buf)
buf->st_size += info.nFileSizeLow;
/* Convert timestamps to Unix format. */
- buf->st_mtime = convert_time (info.ftLastWriteTime);
- buf->st_atime = convert_time (info.ftLastAccessTime);
- if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
- buf->st_ctime = convert_time (info.ftCreationTime);
- if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+ buf->st_mtime = convert_time (info.ftLastWriteTime, &buf->st_mtimensec);
+ buf->st_atime = convert_time (info.ftLastAccessTime, &buf->st_atimensec);
+ if (buf->st_atime == 0)
+ {
+ buf->st_atime = buf->st_mtime;
+ buf->st_atimensec = buf->st_mtimensec;
+ }
+ buf->st_ctime = convert_time (info.ftCreationTime, &buf->st_ctimensec);
+ if (buf->st_ctime == 0)
+ {
+ buf->st_ctime = buf->st_mtime;
+ buf->st_ctimensec = buf->st_mtimensec;
+ }
/* determine rwx permissions */
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
diff --git a/nt/inc/sys/stat.h b/nt/inc/sys/stat.h
index 3aa70f3052e..c93923fd9e8 100644
--- a/nt/inc/sys/stat.h
+++ b/nt/inc/sys/stat.h
@@ -108,6 +108,9 @@ struct stat {
time_t st_ctime;
char st_uname[260];
char st_gname[260];
+ int st_atimensec;
+ int st_mtimensec;
+ int st_ctimensec;
};
/* These are here to avoid compiler warnings when using wchar.h. */
diff --git a/src/w32.c b/src/w32.c
index d7bf173ce25..c504c141b31 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -5076,9 +5076,10 @@ initialize_utc_base (void)
}
static time_t
-convert_time (FILETIME ft)
+convert_time (FILETIME ft, int *time_nsec)
{
ULONGLONG tmp;
+ time_t time_sec;
if (!init)
{
@@ -5090,7 +5091,10 @@ convert_time (FILETIME ft)
return 0;
FILETIME_TO_U64 (tmp, ft);
- return (time_t) ((tmp - utc_base) / 10000000L);
+ tmp -= utc_base;
+ time_sec = (time_t) (tmp / 10000000L);
+ *time_nsec = (tmp - (ULONGLONG) time_sec * 10000000L) * 100L;
+ return time_sec;
}
static void
@@ -5707,11 +5711,19 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
buf->st_nlink = nlinks;
/* Convert timestamps to Unix format. */
- buf->st_mtime = convert_time (wtime);
- buf->st_atime = convert_time (atime);
- if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
- buf->st_ctime = convert_time (ctime);
- if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+ buf->st_mtime = convert_time (wtime, &buf->st_mtimensec);
+ buf->st_atime = convert_time (atime, &buf->st_atimensec);
+ if (buf->st_atime == 0)
+ {
+ buf->st_atime = buf->st_mtime;
+ buf->st_atimensec = buf->st_mtimensec;
+ }
+ buf->st_ctime = convert_time (ctime, &buf->st_ctimensec);
+ if (buf->st_ctime == 0)
+ {
+ buf->st_ctime = buf->st_mtime;
+ buf->st_ctimensec = buf->st_mtimensec;
+ }
/* determine rwx permissions */
if (is_a_symlink && !follow_symlinks)
@@ -5853,11 +5865,19 @@ fstat (int desc, struct stat * buf)
buf->st_size += info.nFileSizeLow;
/* Convert timestamps to Unix format. */
- buf->st_mtime = convert_time (info.ftLastWriteTime);
- buf->st_atime = convert_time (info.ftLastAccessTime);
- if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
- buf->st_ctime = convert_time (info.ftCreationTime);
- if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+ buf->st_mtime = convert_time (info.ftLastWriteTime, &buf->st_mtimensec);
+ buf->st_atime = convert_time (info.ftLastAccessTime, &buf->st_atimensec);
+ if (buf->st_atime == 0)
+ {
+ buf->st_atime = buf->st_mtime;
+ buf->st_atimensec = buf->st_mtimensec;
+ }
+ buf->st_ctime = convert_time (info.ftCreationTime, &buf->st_ctimensec);
+ if (buf->st_ctime == 0)
+ {
+ buf->st_ctime = buf->st_mtime;
+ buf->st_ctimensec = buf->st_mtimensec;
+ }
/* determine rwx permissions */
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)