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
This commit is contained in:
Lasse Collin 2016-06-30 20:27:36 +03:00
parent 1b0ac0c53c
commit 446e4318fa
2 changed files with 19 additions and 1 deletions

View File

@ -672,7 +672,7 @@ AC_C_BIGENDIAN
gl_GETOPT gl_GETOPT
# Find the best function to set timestamps. # 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. # This is nice to have but not mandatory.
AC_CHECK_FUNCS([posix_fadvise]) AC_CHECK_FUNCS([posix_fadvise])

View File

@ -23,6 +23,8 @@ static bool warn_fchown;
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES) #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
# include <sys/time.h> # include <sys/time.h>
#elif defined(HAVE__FUTIME)
# include <sys/utime.h>
#elif defined(HAVE_UTIME) #elif defined(HAVE_UTIME)
# include <utime.h> # include <utime.h>
#endif #endif
@ -457,6 +459,22 @@ io_copy_attrs(const file_pair *pair)
(void)utimes(pair->dest_name, tv); (void)utimes(pair->dest_name, tv);
# endif # 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) #elif defined(HAVE_UTIME)
// Use one-second precision. utime() doesn't support using file // Use one-second precision. utime() doesn't support using file
// descriptor either. Some systems have broken utime() prototype // descriptor either. Some systems have broken utime() prototype