- Reduced memory usage for an incremental transfer that has a bunch of small
diretories.
- - Add support for `--atimes` on macOS.
+ - Added support for `--atimes` on macOS and fix using using it without -t.
- Rsync can now update the xattrs on a read-only file when your user can
temporarily add user-write permission to the file. (It always worked for a
return;
}
}
- sx.crtime = 0;
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
int i;
static inline void
init_stat_x(stat_x *sx_p)
{
+ sx_p->crtime = 0;
#ifdef SUPPORT_ACLS
sx_p->acc_acl = sx_p->def_acl = NULL;
#endif
0. `--omit-dir-times`, `-O`
- This tells rsync to omit directories when it is preserving modification
- times (see `--times`). If NFS is sharing the directories on the receiving
+ This tells rsync to omit directories when it is preserving modification,
+ access, and create times. If NFS is sharing the directories on the receiving
side, it is a good idea to use `-O`. This option is inferred if you use
`--backup` without `--backup-dir`.
0. `--omit-link-times`, `-J`
- This tells rsync to omit symlinks when it is preserving modification times
- (see `--times`).
+ This tells rsync to omit symlinks when it is preserving modification,
+ access, and create times.
0. `--super`
#define UPDATED_ATIME (1<<3)
#define UPDATED_ACLS (1<<4)
#define UPDATED_MODE (1<<5)
-
-#define UPDATED_TIMES (UPDATED_MTIME|UPDATED_ATIME)
+#define UPDATED_CRTIME (1<<6)
#ifdef ICONV_CONST
iconv_t ic_chck = (iconv_t)-1;
set_xattr(fname, file, fnamecmp, sxp);
#endif
- if (!preserve_times
- || (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
- || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
- flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME;
+ if (!preserve_times)
+ flags |= ATTRS_SKIP_MTIME | (atimes_ndx ? 0 : ATTRS_SKIP_ATIME) | (crtimes_ndx ? 0 : ATTRS_SKIP_CRTIME);
+ else if ((!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
+ || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
+ flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME;
else if (sxp != &sx2)
memcpy(&sx2.st, &sxp->st, sizeof (sx2.st));
if (!atimes_ndx || S_ISDIR(sxp->st.st_mode))
updated |= UPDATED_ATIME;
}
}
- if (updated & UPDATED_TIMES) {
+#ifdef SUPPORT_CRTIMES
+ if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
+ time_t file_crtime = F_CRTIME(file);
+ if (sxp->crtime == 0)
+ sxp->crtime = get_create_time(fname, &sxp->st);
+ if (!same_time(sxp->crtime, 0L, file_crtime, 0L)) {
+ if (
+#ifdef HAVE_GETATTRLIST
+ do_setattrlist_crtime(fname, file_crtime) == 0
+#elif defined __CYGWIN__
+ do_SetFileTime(fname, file_crtime) == 0
+#else
+#error Unknown crtimes implementation
+#endif
+ )
+ updated |= UPDATED_CRTIME;
+ }
+ }
+#endif
+ if (updated & (UPDATED_MTIME|UPDATED_ATIME)) {
int ret = set_times(fname, &sx2.st);
if (ret < 0) {
- rsyserr(FERROR_XFER, errno, "failed to set times on %s",
- full_fname(fname));
+ rsyserr(FERROR_XFER, errno, "failed to set times on %s", full_fname(fname));
goto cleanup;
}
if (ret > 0) { /* ret == 1 if symlink could not be set */
- updated &= ~UPDATED_TIMES;
+ updated &= ~(UPDATED_MTIME|UPDATED_ATIME);
file->flags |= FLAG_TIME_FAILED;
}
}
-#ifdef SUPPORT_CRTIMES
- if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
- time_t file_crtime = F_CRTIME(file);
- if (sxp->crtime == 0)
- sxp->crtime = get_create_time(fname, &sxp->st);
- if (!same_time(sxp->crtime, 0L, file_crtime, 0L)
- && set_create_time(fname, file_crtime) == 0)
- updated = 1;
- }
-#endif
#ifdef SUPPORT_ACLS
/* It's OK to call set_acl() now, even for a dir, as the generator
{
static int switch_step = 0;
int code;
+
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
+
switch (switch_step) {
#ifdef HAVE_LCHMOD
case 0:
attrList.commonattr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME;
return setattrlist(path, &attrList, ts, sizeof ts, FSOPT_NOFOLLOW);
}
+
+#ifdef SUPPORT_CRTIMES
+int do_setattrlist_crtime(const char *path, time_t crtime)
+{
+ struct attrlist attrList;
+ struct timespec ts;
+
+ if (dry_run) return 0;
+ RETURN_ERROR_IF_RO_OR_LO;
+
+ ts.tv_sec = crtime;
+ ts.tv_nsec = 0;
+
+ memset(&attrList, 0, sizeof attrList);
+ attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrList.commonattr = ATTR_CMN_CRTIME;
+ return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
+}
#endif
+#endif /* HAVE_SETATTRLIST */
#ifdef SUPPORT_CRTIMES
time_t get_create_time(const char *path, STRUCT_STAT *stp)
#endif
}
-int set_create_time(const char *path, time_t crtime)
+#if defined __CYGWIN__
+int do_SetFileTime(const char *path, time_t crtime)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
- {
-#ifdef HAVE_GETATTRLIST
- struct attrlist attrList;
- struct timespec ts;
-
- ts.tv_sec = crtime;
- ts.tv_nsec = 0;
-
- memset(&attrList, 0, sizeof attrList);
- attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
- attrList.commonattr = ATTR_CMN_CRTIME;
- return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
-#elif defined __CYGWIN__
int cnt = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
if (cnt == 0)
return -1;
int ok = SetFileTime(handle, &birth_time, NULL, NULL);
CloseHandle(handle);
return ok ? 0 : -1;
-#endif
- }
}
+#endif
#endif /* SUPPORT_CRTIMES */
#ifdef HAVE_UTIMENSAT