bug-gnulib
[Top][All Lists]
Advanced

[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]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]