aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/xz/file_io.c18
2 files changed, 19 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index b8fcf1ef..46e51607 100644
--- a/configure.ac
+++ b/configure.ac
@@ -648,7 +648,7 @@ AC_C_BIGENDIAN
gl_GETOPT
# Find the best function to set timestamps.
-AC_CHECK_FUNCS([futimens futimes futimesat utimes utime], [break])
+AC_CHECK_FUNCS([futimens futimes futimesat utimes _futime utime], [break])
# This is nice to have but not mandatory.
AC_CHECK_FUNCS([posix_fadvise])
diff --git a/src/xz/file_io.c b/src/xz/file_io.c
index a8baa29d..91876bf9 100644
--- a/src/xz/file_io.c
+++ b/src/xz/file_io.c
@@ -23,6 +23,8 @@ static bool warn_fchown;
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
# include <sys/time.h>
+#elif defined(HAVE__FUTIME)
+# include <sys/utime.h>
#elif defined(HAVE_UTIME)
# include <utime.h>
#endif
@@ -377,6 +379,22 @@ io_copy_attrs(const file_pair *pair)
(void)utimes(pair->dest_name, tv);
# endif
+#elif defined(HAVE__FUTIME)
+ // Use one-second precision with Windows-specific _futime().
+ // We could use utime() too except that for some reason the
+ // timestamp will get reset at close(). With _futime() it works.
+ // This struct cannot be const as _futime() takes a non-const pointer.
+ struct _utimbuf buf = {
+ .actime = pair->src_st.st_atime,
+ .modtime = pair->src_st.st_mtime,
+ };
+
+ // Avoid warnings.
+ (void)atime_nsec;
+ (void)mtime_nsec;
+
+ (void)_futime(pair->dest_fd, &buf);
+
#elif defined(HAVE_UTIME)
// Use one-second precision. utime() doesn't support using file
// descriptor either. Some systems have broken utime() prototype