Add nanosecond mtime support for Mac OS X.
authorWayne Davison <wayned@samba.org>
Thu, 31 Aug 2017 15:22:14 +0000 (08:22 -0700)
committerWayne Davison <wayned@samba.org>
Thu, 31 Aug 2017 15:22:14 +0000 (08:22 -0700)
Slightly tweaked the patch contributed by Heikki Lindholm.

configure.ac
flist.c
rsync.h
syscall.c
util.c

index e01e124bfb84b5ffba33f3f1b586bf4fc1228776..02d4cb844ecf9ea1ca2c94825d6ab2522239d24c 100644 (file)
@@ -400,6 +400,7 @@ AC_CHECK_TYPES([mode_t,off_t,size_t,pid_t,id_t])
 AC_TYPE_GETGROUPS
 AC_CHECK_MEMBERS([struct stat.st_rdev,
                  struct stat.st_mtimensec,
+                 struct stat.st_mtimespec.tv_nsec,
                  struct stat.st_mtim.tv_nsec],,,[
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
diff --git a/flist.c b/flist.c
index 28553fc3dab16f3b953a085c2528aceeef9f9204..24b3506fcb36287c54991f7a4ab1fb2d2e344129 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -895,7 +895,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        if (file_length > 0xFFFFFFFFu && S_ISREG(mode))
                extra_len += EXTRA_LEN;
 #endif
-#ifdef HAVE_UTIMENSAT
+#ifdef CAN_SET_NSEC
        if (modtime_nsec)
                extra_len += EXTRA_LEN;
 #endif
@@ -941,7 +941,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                file->flags |= FLAG_HLINKED;
 #endif
        file->modtime = (time_t)modtime;
-#ifdef HAVE_UTIMENSAT
+#ifdef CAN_SET_NSEC
        if (modtime_nsec) {
                file->flags |= FLAG_MOD_NSEC;
                OPT_EXTRA(file, 0)->unum = modtime_nsec;
diff --git a/rsync.h b/rsync.h
index 1720293d50f379f6a56a0f105cfe9430edb357c1..c51e8d3b8123f32054d8922bb574a44da0b38413 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -372,7 +372,7 @@ enum delret {
 #include <utime.h>
 #endif
 
-#if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES
+#if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES || defined HAVE_SETATTRLIST
 #define CAN_SET_SYMLINK_TIMES 1
 #endif
 
@@ -384,11 +384,17 @@ enum delret {
 #define CAN_CHMOD_SYMLINK 1
 #endif
 
-#ifdef HAVE_UTIMENSAT
+#if defined HAVE_UTIMENSAT || defined HAVE_SETATTRLIST
+#define CAN_SET_NSEC 1
+#endif
+
+#ifdef CAN_SET_NSEC
 #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
 #define ST_MTIME_NSEC st_mtim.tv_nsec
 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
 #define ST_MTIME_NSEC st_mtimensec
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+#define ST_MTIME_NSEC st_mtimespec.tv_nsec
 #endif
 #endif
 
index d89eacd57fb4de608ddc88aef21f4e145ac02a46..dae92bc21cea286add0ae7d838af541685642d4f 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -360,6 +360,25 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
 #endif
 }
 
+#ifdef HAVE_SETATTRLIST
+int do_setattrlist_times(const char *fname, time_t modtime, uint32 mod_nsec)
+{
+       struct attrlist attrList;
+       struct timespec ts;
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       ts.tv_sec = modtime;
+       ts.tv_nsec = mod_nsec;
+
+       memset(&attrList, 0, sizeof attrList);
+       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
+       attrList.commonattr = ATTR_CMN_MODTIME;
+       return setattrlist(fname, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
+}
+#endif
+
 #ifdef HAVE_UTIMENSAT
 int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec)
 {
diff --git a/util.c b/util.c
index 49c5b716edf874d5ee32a9774a32661e3962f5ed..d50900c8d387747a76b51f25abb0ac8dd4051252 100644 (file)
--- a/util.c
+++ b/util.c
@@ -128,6 +128,16 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
        }
 
        switch (switch_step) {
+#ifdef HAVE_SETATTRLIST
+#include "case_N.h"
+               if (do_setattrlist_times(fname, modtime, mod_nsec) == 0)
+                       break;
+               if (errno != ENOSYS)
+                       return -1;
+               switch_step++;
+               /* FALLTHROUGH */
+#endif
+
 #ifdef HAVE_UTIMENSAT
 #include "case_N.h"
                if (do_utimensat(fname, modtime, mod_nsec) == 0)