libarchive - Ensure futimens() operation is consistent with utimes()
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 6 Jun 2015 18:20:21 +0000 (11:20 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 6 Jun 2015 18:20:21 +0000 (11:20 -0700)
* utimes() allows tv_sec to be -1 to indicate that the element should
  not be updated.

* Handle this case for when futimens() is used by setting tv_nsec to
  UTIME_OMIT.

* This way operation is consistent whether we use futimens() or use
  utimes().

contrib/libarchive/libarchive/archive_read_disk_posix.c
contrib/libarchive/libarchive/archive_write_disk_posix.c

index a91c12d..2d5322d 100644 (file)
@@ -1918,11 +1918,21 @@ close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
        }
 
 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
-       timespecs[1].tv_sec = rt->mtime;
-       timespecs[1].tv_nsec = rt->mtime_nsec;
+       if (rt->mtime == (time_t)-1) {
+               timespecs[1].tv_sec = 0;
+               timespecs[1].tv_nsec = UTIME_OMIT;
+       } else {
+               timespecs[1].tv_sec = rt->mtime;
+               timespecs[1].tv_nsec = rt->mtime_nsec;
+       }
 
-       timespecs[0].tv_sec = rt->atime;
-       timespecs[0].tv_nsec = rt->atime_nsec;
+       if (rt->atime == (time_t)-1) {
+               timespecs[0].tv_sec = 0;
+               timespecs[0].tv_nsec = UTIME_OMIT;
+       } else {
+               timespecs[0].tv_sec = rt->atime;
+               timespecs[0].tv_nsec = rt->atime_nsec;
+       }
        /* futimens() is defined in POSIX.1-2008. */
        if (futimens(fd, timespecs) == 0)
                return (close(fd));
index bbd50a6..9d25448 100644 (file)
@@ -2795,10 +2795,20 @@ set_time(int fd, int mode, const char *name,
         */
        struct timespec ts[2];
        (void)mode; /* UNUSED */
-       ts[0].tv_sec = atime;
-       ts[0].tv_nsec = atime_nsec;
-       ts[1].tv_sec = mtime;
-       ts[1].tv_nsec = mtime_nsec;
+       if (atime == (time_t)-1) {
+               ts[0].tv_sec = 0;
+               ts[0].tv_nsec = UTIME_OMIT;
+       } else {
+               ts[0].tv_sec = atime;
+               ts[0].tv_nsec = atime_nsec;
+       }
+       if (mtime == (time_t)-1) {
+               ts[1].tv_sec = 0;
+               ts[1].tv_nsec = UTIME_OMIT;
+       } else {
+               ts[1].tv_sec = mtime;
+               ts[1].tv_nsec = mtime_nsec;
+       }
        if (fd >= 0)
                return futimens(fd, ts);
        return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW);