summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2025-05-11 13:33:24 +0300
committerEli Zaretskii <eliz@gnu.org>2025-05-11 13:33:24 +0300
commit3975094f1d96680fe73232ca4216733904ebecd0 (patch)
tree9944f35bd730451694fc81960c71581ed3416550 /lib-src
parent9df2074a06fefa0b5bfe9714b45c383fa45d6650 (diff)
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/>. */
#include <direct.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <math.h>
#include <errno.h>
#include <ctype.h>
#include <sys/timeb.h>
@@ -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)