aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2016-06-30 20:27:36 +0300
committerLasse Collin <lasse.collin@tukaani.org>2016-06-30 20:27:36 +0300
commit446e4318fa79788e09299d5953b5dd428953d14b (patch)
tree23fe6d61a55d263620137cbe36b6b9e60f6646ab
parentxz: Silence warnings from -Wlogical-op. (diff)
downloadxz-446e4318fa79788e09299d5953b5dd428953d14b.tar.xz
xz: Fix copying of timestamps on Windows.
xz used to call utime() on Windows, but its result gets lost on close(). Using _futime() seems to work. Thanks to Martok for reporting the bug: http://www.mail-archive.com/xz-devel@tukaani.org/msg00261.html
-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 3df43486..81abce58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -672,7 +672,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 2ca188bd..c01f4e8b 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
@@ -457,6 +459,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