diff options
author | Wayne Davison <wayne@opencoder.net> | 2021-10-10 11:45:14 -0700 |
---|---|---|
committer | Wayne Davison <wayne@opencoder.net> | 2021-10-10 12:43:11 -0700 |
commit | 296352ecb0175fa3c37de550dd57aeff39632095 (patch) | |
tree | e58ac282baece4520265699b155b2c97c3496042 | |
parent | 11a9b623226ef2324985958c3416d2bae5a3b7f3 (diff) | |
download | rsync-296352ecb0175fa3c37de550dd57aeff39632095.tar.gz |
Tweak atime/crtime code a bit more.
-rw-r--r-- | NEWS.md | 2 | ||||
-rw-r--r-- | generator.c | 1 | ||||
-rw-r--r-- | ifuncs.h | 1 | ||||
-rw-r--r-- | rsync.1.md | 8 | ||||
-rw-r--r-- | rsync.c | 48 | ||||
-rw-r--r-- | syscall.c | 40 |
6 files changed, 58 insertions, 42 deletions
@@ -51,7 +51,7 @@ - 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 diff --git a/generator.c b/generator.c index 3287ae31..9c9751dc 100644 --- a/generator.c +++ b/generator.c @@ -1269,7 +1269,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, return; } } - sx.crtime = 0; if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) { int i; @@ -75,6 +75,7 @@ d_name(struct dirent *di) 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 @@ -1391,8 +1391,8 @@ your home directory (remove the '=' for that). 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`. @@ -1409,8 +1409,8 @@ your home directory (remove the '=' for that). 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` @@ -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 @@ -233,8 +233,10 @@ int do_chmod(const char *path, mode_t mode) { 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: @@ -415,7 +417,26 @@ int do_setattrlist_times(const char *path, STRUCT_STAT *stp) 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) @@ -439,24 +460,12 @@ 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; @@ -476,9 +485,8 @@ int set_create_time(const char *path, time_t crtime) int ok = SetFileTime(handle, &birth_time, NULL, NULL); CloseHandle(handle); return ok ? 0 : -1; -#endif - } } +#endif #endif /* SUPPORT_CRTIMES */ #ifdef HAVE_UTIMENSAT |