[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: utimens: support for native Windows
From: |
Bruno Haible |
Subject: |
Re: utimens: support for native Windows |
Date: |
Mon, 08 May 2017 12:02:42 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-75-generic; KDE/5.18.0; x86_64; ; ) |
Oops, I had verified the subsecond resolution support (through Cygwin's 'ls',
as "ls -l --full-time") only for the case fd >= 0. For the case fd < 0, this
patch adds the subsecond resolution support.
2017-05-07 Bruno Haible <address@hidden>
utimens: On native Windows, support 100ns resolution also if fd < 0.
* lib/utime.in.h: Include <time.h>.
(_gl_utimens_windows): New declaration.
* lib/utime.c (_gl_utimens_windows): New function, based on utime.
(utime): Invoke it.
* lib/utimens.c (fdutimens): On native Windows, call _gl_utimens_windows
instead of utime.
* modules/utime (Depends-on): Add 'time'.
diff --git a/lib/utime.c b/lib/utime.c
index 230d36b..6226934 100644
--- a/lib/utime.c
+++ b/lib/utime.c
@@ -30,7 +30,7 @@
# include "malloca.h"
int
-utime (const char *name, const struct utimbuf *ts)
+_gl_utimens_windows (const char *name, struct timespec ts[2])
{
/* POSIX
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>
specifies: "More than two leading <slash> characters shall be treated as
@@ -146,13 +146,13 @@ utime (const char *name, const struct utimbuf *ts)
{
{
ULONGLONG time_since_16010101 =
- (ULONGLONG) ts->actime * 10000000 + 116444736000000000LL;
+ (ULONGLONG) ts[0].tv_sec * 10000000 + ts[0].tv_nsec / 100 +
116444736000000000LL;
last_access_time.dwLowDateTime = (DWORD) time_since_16010101;
last_access_time.dwHighDateTime = time_since_16010101 >> 32;
}
{
ULONGLONG time_since_16010101 =
- (ULONGLONG) ts->modtime * 10000000 + 116444736000000000LL;
+ (ULONGLONG) ts[1].tv_sec * 10000000 + ts[1].tv_nsec / 100 +
116444736000000000LL;
last_write_time.dwLowDateTime = (DWORD) time_since_16010101;
last_write_time.dwHighDateTime = time_since_16010101 >> 32;
}
@@ -168,7 +168,7 @@ utime (const char *name, const struct utimbuf *ts)
{
#if 0
DWORD sft_error = GetLastError ();
- fprintf (stderr, "utime SetFileTime error 0x%x\n", (unsigned int)
sft_error);
+ fprintf (stderr, "utimens SetFileTime error 0x%x\n", (unsigned int)
sft_error);
#endif
CloseHandle (handle);
if (malloca_rname != NULL)
@@ -181,7 +181,7 @@ utime (const char *name, const struct utimbuf *ts)
failed:
{
#if 0
- fprintf (stderr, "utime CreateFile/GetFileAttributes error 0x%x\n",
(unsigned int) error);
+ fprintf (stderr, "utimens CreateFile/GetFileAttributes error 0x%x\n",
(unsigned int) error);
#endif
if (malloca_rname != NULL)
freea (malloca_rname);
@@ -237,4 +237,20 @@ utime (const char *name, const struct utimbuf *ts)
}
}
+int
+utime (const char *name, const struct utimbuf *ts)
+{
+ if (ts == NULL)
+ return _gl_utimens_windows (name, NULL);
+ else
+ {
+ struct timespec ts_with_nanoseconds[2];
+ ts_with_nanoseconds[0].tv_sec = ts->actime;
+ ts_with_nanoseconds[0].tv_nsec = 0;
+ ts_with_nanoseconds[1].tv_sec = ts->modtime;
+ ts_with_nanoseconds[1].tv_nsec = 0;
+ return _gl_utimens_windows (name, ts_with_nanoseconds);
+ }
+}
+
#endif
diff --git a/lib/utime.in.h b/lib/utime.in.h
index 8847e72..df80d8c 100644
--- a/lib/utime.in.h
+++ b/lib/utime.in.h
@@ -33,6 +33,11 @@
# include <sys/utime.h>
#endif
+#if @GNULIB_UTIME@
+/* Get struct timespec. */
+# include <time.h>
+#endif
+
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
/* The definition of _GL_ARG_NONNULL is copied here. */
@@ -74,6 +79,10 @@ _GL_WARN_ON_USE (utime,
# endif
#endif
+#if @GNULIB_UTIME@
+extern int _gl_utimens_windows (const char *filename, struct timespec ts[2]);
+#endif
+
#endif /* address@hidden@_UTIME_H */
#endif /* address@hidden@_UTIME_H */
diff --git a/lib/utimens.c b/lib/utimens.c
index b027cfb..b4bfa8e 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -473,7 +473,9 @@ fdutimens (int fd, char const *file, struct timespec const
timespec[2])
return -1;
}
-#if HAVE_WORKING_UTIMES
+#ifdef USE_SETFILETIME
+ return _gl_utimens_windows (file, ts);
+#elif HAVE_WORKING_UTIMES
return utimes (file, t);
#else
{
diff --git a/modules/utime b/modules/utime
index 545a24c..0fc34eb 100644
--- a/modules/utime
+++ b/modules/utime
@@ -7,6 +7,7 @@ m4/utime.m4
Depends-on:
utime-h
+time
filename [test $HAVE_UTIME = 0 || test $REPLACE_UTIME = 1]
malloca [test $HAVE_UTIME = 0 || test $REPLACE_UTIME = 1]