From 296352ecb0175fa3c37de550dd57aeff39632095 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sun, 10 Oct 2021 11:45:14 -0700 Subject: Tweak atime/crtime code a bit more. --- rsync.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'rsync.c') diff --git a/rsync.c b/rsync.c index bcecac63..ff9489be 100644 --- a/rsync.c +++ b/rsync.c @@ -63,8 +63,7 @@ extern char *iconv_opt; #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; @@ -576,10 +575,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 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)) @@ -604,28 +604,36 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, 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 -- cgit v1.2.1