summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-05-01 15:33:06 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-05-01 15:33:26 -0700
commit634d0a907ff7ba5901dfe3624e58d718f3f37cec (patch)
tree6bf86cf04d8b28a79693df9cdef1063c9b06ca76 /lib
parent16b49e214ad828de29ceb57ad1b443eece9bba03 (diff)
downloademacs-634d0a907ff7ba5901dfe3624e58d718f3f37cec.tar.gz
Merge from gnulib
This incorporates: 2017-05-01 New module 'localtime-buffer' 2017-04-30 utimens: Add support for native Windows * admin/merge-gnulib (AVOIDED_MODULES): Add tzset. * configure.ac (tzset): No need for Emacs itself to check now. * lib/gettimeofday.c, lib/time.in.h, lib/time_rz.c, lib/utimens.c: * m4/gettimeofday.m4, m4/time_h.m4, m4/time_rz.m4: Copy from gnulib. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lib/localtime-buffer.c, lib/localtime-buffer.h: * m4/localtime-buffer.m4: New files, copied from gnulib. * src/editfns.c (init_editfns): Assume tzset is callable.
Diffstat (limited to 'lib')
-rw-r--r--lib/gettimeofday.c73
-rw-r--r--lib/gnulib.mk.in23
-rw-r--r--lib/localtime-buffer.c58
-rw-r--r--lib/localtime-buffer.h27
-rw-r--r--lib/time.in.h22
-rw-r--r--lib/time_rz.c4
-rw-r--r--lib/utimens.c82
7 files changed, 214 insertions, 75 deletions
diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index 86f1a8c1d28..1039f77d182 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -29,72 +29,7 @@
# include <windows.h>
#endif
-#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
-
-/* Work around the bug in some systems whereby gettimeofday clobbers
- the static buffer that localtime uses for its return value. The
- gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
- this problem. The tzset replacement is necessary for at least
- Solaris 2.5, 2.5.1, and 2.6. */
-
-static struct tm tm_zero_buffer;
-static struct tm *localtime_buffer_addr = &tm_zero_buffer;
-
-# undef localtime
-extern struct tm *localtime (time_t const *);
-
-# undef gmtime
-extern struct tm *gmtime (time_t const *);
-
-/* This is a wrapper for localtime. It is used only on systems for which
- gettimeofday clobbers the static buffer used for localtime's result.
-
- On the first call, record the address of the static buffer that
- localtime uses for its result. */
-
-struct tm *
-rpl_localtime (time_t const *timep)
-{
- struct tm *tm = localtime (timep);
-
- if (localtime_buffer_addr == &tm_zero_buffer)
- localtime_buffer_addr = tm;
-
- return tm;
-}
-
-/* Same as above, since gmtime and localtime use the same buffer. */
-struct tm *
-rpl_gmtime (time_t const *timep)
-{
- struct tm *tm = gmtime (timep);
-
- if (localtime_buffer_addr == &tm_zero_buffer)
- localtime_buffer_addr = tm;
-
- return tm;
-}
-
-#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
-
-#if TZSET_CLOBBERS_LOCALTIME
-
-# undef tzset
-extern void tzset (void);
-
-/* This is a wrapper for tzset, for systems on which tzset may clobber
- the static buffer used for localtime's result. */
-void
-rpl_tzset (void)
-{
- /* Save and restore the contents of the buffer used for localtime's
- result around the call to tzset. */
- struct tm save = *localtime_buffer_addr;
- tzset ();
- *localtime_buffer_addr = save;
-}
-
-#endif
+#include "localtime-buffer.h"
#ifdef WINDOWS_NATIVE
@@ -119,7 +54,11 @@ initialize (void)
/* This is a wrapper for gettimeofday. It is used only on systems
that lack this function, or whose implementation of this function
- causes problems. */
+ causes problems.
+ Work around the bug in some systems whereby gettimeofday clobbers
+ the static buffer that localtime uses for its return value. The
+ gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
+ this problem. */
int
gettimeofday (struct timeval *restrict tv, void *restrict tz)
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 59cdbdb847a..51ae1891244 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings
+# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings
MOSTLYCLEANFILES += core *.stackdump
@@ -307,6 +307,7 @@ GNULIB_TIME_R = @GNULIB_TIME_R@
GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
GNULIB_TMPFILE = @GNULIB_TMPFILE@
GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_TZSET = @GNULIB_TZSET@
GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
GNULIB_UNLINK = @GNULIB_UNLINK@
@@ -504,6 +505,7 @@ HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
HAVE_TIMEGM = @HAVE_TIMEGM@
HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_TZSET = @HAVE_TZSET@
HAVE_UNISTD_H = @HAVE_UNISTD_H@
HAVE_UNLINKAT = @HAVE_UNLINKAT@
HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
@@ -780,6 +782,7 @@ REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
REPLACE_TIMEGM = @REPLACE_TIMEGM@
REPLACE_TMPFILE = @REPLACE_TMPFILE@
REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_TZSET = @REPLACE_TZSET@
REPLACE_UNLINK = @REPLACE_UNLINK@
REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
REPLACE_UNSETENV = @REPLACE_UNSETENV@
@@ -879,6 +882,7 @@ gamedir = @gamedir@
gamegroup = @gamegroup@
gameuser = @gameuser@
gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7 = @gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7@
+gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9 = @gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9@
gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b@
gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@
gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@
@@ -1700,6 +1704,19 @@ EXTRA_DIST += limits.in.h
endif
## end gnulib module limits-h
+## begin gnulib module localtime-buffer
+ifeq (,$(OMIT_GNULIB_MODULE_localtime-buffer))
+
+ifneq (,$(gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9))
+
+endif
+EXTRA_DIST += localtime-buffer.c localtime-buffer.h
+
+EXTRA_libgnu_a_SOURCES += localtime-buffer.c
+
+endif
+## end gnulib module localtime-buffer
+
## begin gnulib module lstat
ifeq (,$(OMIT_GNULIB_MODULE_lstat))
@@ -2707,7 +2724,6 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \
-e 's/@''GNULIB_CTIME''@/$(GNULIB_CTIME)/g' \
- -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GNULIB_GETTIMEOFDAY)/g' \
-e 's/@''GNULIB_LOCALTIME''@/$(GNULIB_LOCALTIME)/g' \
-e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \
-e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \
@@ -2716,11 +2732,13 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
-e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
+ -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
-e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
-e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
+ -e 's|@''HAVE_TZSET''@|$(HAVE_TZSET)|g' \
-e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \
-e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
-e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
@@ -2729,6 +2747,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \
-e 's|@''REPLACE_STRFTIME''@|$(REPLACE_STRFTIME)|g' \
-e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \
+ -e 's|@''REPLACE_TZSET''@|$(REPLACE_TZSET)|g' \
-e 's|@''PTHREAD_H_DEFINES_STRUCT_TIMESPEC''@|$(PTHREAD_H_DEFINES_STRUCT_TIMESPEC)|g' \
-e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
-e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
diff --git a/lib/localtime-buffer.c b/lib/localtime-buffer.c
new file mode 100644
index 00000000000..f84ad3e8238
--- /dev/null
+++ b/lib/localtime-buffer.c
@@ -0,0 +1,58 @@
+/* Provide access to the last buffer returned by localtime() or gmtime().
+
+ Copyright (C) 2001-2003, 2005-2007, 2009-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+/* Specification. */
+#include "localtime-buffer.h"
+
+#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
+
+static struct tm tm_zero_buffer;
+struct tm *localtime_buffer_addr = &tm_zero_buffer;
+
+/* This is a wrapper for localtime.
+
+ On the first call, record the address of the static buffer that
+ localtime uses for its result. */
+
+struct tm *
+rpl_localtime (time_t const *timep)
+{
+ struct tm *tm = localtime (timep);
+
+ if (localtime_buffer_addr == &tm_zero_buffer)
+ localtime_buffer_addr = tm;
+
+ return tm;
+}
+
+/* Same as above, since gmtime and localtime use the same buffer. */
+struct tm *
+rpl_gmtime (time_t const *timep)
+{
+ struct tm *tm = gmtime (timep);
+
+ if (localtime_buffer_addr == &tm_zero_buffer)
+ localtime_buffer_addr = tm;
+
+ return tm;
+}
+
+#endif
diff --git a/lib/localtime-buffer.h b/lib/localtime-buffer.h
new file mode 100644
index 00000000000..483a579bda4
--- /dev/null
+++ b/lib/localtime-buffer.h
@@ -0,0 +1,27 @@
+/* Provide access to the last buffer returned by localtime() or gmtime().
+
+ Copyright (C) 2001-2003, 2005-2007, 2009-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering */
+
+#include <time.h>
+
+#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
+
+/* The address of the last buffer returned by localtime() or gmtime(). */
+extern struct tm *localtime_buffer_addr;
+
+#endif
diff --git a/lib/time.in.h b/lib/time.in.h
index d2a0302f464..f0c7ef86667 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -120,6 +120,24 @@ _GL_CXXALIAS_SYS (nanosleep, int,
_GL_CXXALIASWARN (nanosleep);
# endif
+/* Initialize time conversion information. */
+# if @GNULIB_TZSET@
+# if @REPLACE_TZSET@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef tzset
+# define tzset rpl_tzset
+# endif
+_GL_FUNCDECL_RPL (tzset, void, (void));
+_GL_CXXALIAS_RPL (tzset, void, (void));
+# else
+# if ! @HAVE_TZSET@
+_GL_FUNCDECL_SYS (tzset, void, (void));
+# endif
+_GL_CXXALIAS_SYS (tzset, void, (void));
+# endif
+_GL_CXXALIASWARN (tzset);
+# endif
+
/* Return the 'time_t' representation of TP and normalize TP. */
# if @GNULIB_MKTIME@
# if @REPLACE_MKTIME@
@@ -187,7 +205,7 @@ _GL_CXXALIASWARN (gmtime_r);
/* Convert TIMER to RESULT, assuming local time and UTC respectively. See
<http://www.opengroup.org/susv3xsh/localtime.html> and
<http://www.opengroup.org/susv3xsh/gmtime.html>. */
-# if @GNULIB_LOCALTIME@ || @GNULIB_GETTIMEOFDAY@
+# if @GNULIB_LOCALTIME@ || @REPLACE_LOCALTIME@
# if @REPLACE_LOCALTIME@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef localtime
@@ -202,7 +220,7 @@ _GL_CXXALIAS_SYS (localtime, struct tm *, (time_t const *__timer));
_GL_CXXALIASWARN (localtime);
# endif
-# if @GNULIB_GETTIMEOFDAY@
+# if 0 || @REPLACE_GMTIME@
# if @REPLACE_GMTIME@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef gmtime
diff --git a/lib/time_rz.c b/lib/time_rz.c
index c41a8ef47ac..17bc11c20e9 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -40,10 +40,6 @@
# define SIZE_MAX ((size_t) -1)
#endif
-#if !HAVE_TZSET
-static void tzset (void) { }
-#endif
-
/* The approximate size to use for small allocation requests. This is
the largest "small" request for the GNU C library malloc. */
enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
diff --git a/lib/utimens.c b/lib/utimens.c
index 3b451193350..0b3b8e2f3af 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -35,6 +35,12 @@
#include "stat-time.h"
#include "timespec.h"
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include "msvc-nothrow.h"
+#endif
+
/* Avoid recursion with rpl_futimens or rpl_utimensat. */
#undef futimens
#undef utimensat
@@ -271,6 +277,82 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On native Windows, use SetFileTime(). See
+ <https://msdn.microsoft.com/en-us/library/ms724933.aspx>
+ <https://msdn.microsoft.com/en-us/library/ms724284.aspx> */
+ if (0 <= fd)
+ {
+ HANDLE handle;
+ FILETIME current_time;
+ FILETIME last_access_time;
+ FILETIME last_write_time;
+
+ handle = (HANDLE) _get_osfhandle (fd);
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ts == NULL || ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW)
+ {
+ /* GetSystemTimeAsFileTime
+ <https://msdn.microsoft.com/en-us/library/ms724397.aspx>.
+ It would be overkill to use
+ GetSystemTimePreciseAsFileTime
+ <https://msdn.microsoft.com/en-us/library/hh706895.aspx>. */
+ GetSystemTimeAsFileTime (&current_time);
+ }
+
+ if (ts == NULL || ts[0].tv_nsec == UTIME_NOW)
+ {
+ last_access_time = current_time;
+ }
+ else if (ts[0].tv_nsec == UTIME_OMIT)
+ {
+ last_access_time.dwLowDateTime = 0;
+ last_access_time.dwHighDateTime = 0;
+ }
+ else
+ {
+ ULONGLONG time_since_16010101 =
+ (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;
+ }
+
+ if (ts == NULL || ts[1].tv_nsec == UTIME_NOW)
+ {
+ last_write_time = current_time;
+ }
+ else if (ts[1].tv_nsec == UTIME_OMIT)
+ {
+ last_write_time.dwLowDateTime = 0;
+ last_write_time.dwHighDateTime = 0;
+ }
+ else
+ {
+ ULONGLONG time_since_16010101 =
+ (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;
+ }
+
+ if (SetFileTime (handle, NULL, &last_access_time, &last_write_time))
+ return 0;
+ else
+ {
+ #if 0
+ DWORD sft_error = GetLastError ();
+ fprintf (stderr, "utime SetFileTime error 0x%x\n", (unsigned int) sft_error);
+ #endif
+ errno = EINVAL;
+ return -1;
+ }
+ }
+#endif
+
/* The platform lacks an interface to set file timestamps with
nanosecond resolution, so do the best we can, discarding any
fractional part of the timestamp. */