Skip to content

Commit 296352e

Browse files
committedOct 10, 2021
Tweak atime/crtime code a bit more.
1 parent 11a9b62 commit 296352e

File tree

6 files changed

+58
-42
lines changed

6 files changed

+58
-42
lines changed
 

‎NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
- Reduced memory usage for an incremental transfer that has a bunch of small
5252
diretories.
5353

54-
- Add support for `--atimes` on macOS.
54+
- Added support for `--atimes` on macOS and fix using using it without -t.
5555

5656
- Rsync can now update the xattrs on a read-only file when your user can
5757
temporarily add user-write permission to the file. (It always worked for a

‎generator.c

-1
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
12691269
return;
12701270
}
12711271
}
1272-
sx.crtime = 0;
12731272

12741273
if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
12751274
int i;

‎ifuncs.h

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ d_name(struct dirent *di)
7575
static inline void
7676
init_stat_x(stat_x *sx_p)
7777
{
78+
sx_p->crtime = 0;
7879
#ifdef SUPPORT_ACLS
7980
sx_p->acc_acl = sx_p->def_acl = NULL;
8081
#endif

‎rsync.1.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,8 @@ your home directory (remove the '=' for that).
13911391

13921392
0. `--omit-dir-times`, `-O`
13931393

1394-
This tells rsync to omit directories when it is preserving modification
1395-
times (see `--times`). If NFS is sharing the directories on the receiving
1394+
This tells rsync to omit directories when it is preserving modification,
1395+
access, and create times. If NFS is sharing the directories on the receiving
13961396
side, it is a good idea to use `-O`. This option is inferred if you use
13971397
`--backup` without `--backup-dir`.
13981398

@@ -1409,8 +1409,8 @@ your home directory (remove the '=' for that).
14091409

14101410
0. `--omit-link-times`, `-J`
14111411

1412-
This tells rsync to omit symlinks when it is preserving modification times
1413-
(see `--times`).
1412+
This tells rsync to omit symlinks when it is preserving modification,
1413+
access, and create times.
14141414

14151415
0. `--super`
14161416

‎rsync.c

+28-20
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ extern char *iconv_opt;
6363
#define UPDATED_ATIME (1<<3)
6464
#define UPDATED_ACLS (1<<4)
6565
#define UPDATED_MODE (1<<5)
66-
67-
#define UPDATED_TIMES (UPDATED_MTIME|UPDATED_ATIME)
66+
#define UPDATED_CRTIME (1<<6)
6867

6968
#ifdef ICONV_CONST
7069
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,
576575
set_xattr(fname, file, fnamecmp, sxp);
577576
#endif
578577

579-
if (!preserve_times
580-
|| (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
581-
|| (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
582-
flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME;
578+
if (!preserve_times)
579+
flags |= ATTRS_SKIP_MTIME | (atimes_ndx ? 0 : ATTRS_SKIP_ATIME) | (crtimes_ndx ? 0 : ATTRS_SKIP_CRTIME);
580+
else if ((!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
581+
|| (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
582+
flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME;
583583
else if (sxp != &sx2)
584584
memcpy(&sx2.st, &sxp->st, sizeof (sx2.st));
585585
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,
604604
updated |= UPDATED_ATIME;
605605
}
606606
}
607-
if (updated & UPDATED_TIMES) {
607+
#ifdef SUPPORT_CRTIMES
608+
if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
609+
time_t file_crtime = F_CRTIME(file);
610+
if (sxp->crtime == 0)
611+
sxp->crtime = get_create_time(fname, &sxp->st);
612+
if (!same_time(sxp->crtime, 0L, file_crtime, 0L)) {
613+
if (
614+
#ifdef HAVE_GETATTRLIST
615+
do_setattrlist_crtime(fname, file_crtime) == 0
616+
#elif defined __CYGWIN__
617+
do_SetFileTime(fname, file_crtime) == 0
618+
#else
619+
#error Unknown crtimes implementation
620+
#endif
621+
)
622+
updated |= UPDATED_CRTIME;
623+
}
624+
}
625+
#endif
626+
if (updated & (UPDATED_MTIME|UPDATED_ATIME)) {
608627
int ret = set_times(fname, &sx2.st);
609628
if (ret < 0) {
610-
rsyserr(FERROR_XFER, errno, "failed to set times on %s",
611-
full_fname(fname));
629+
rsyserr(FERROR_XFER, errno, "failed to set times on %s", full_fname(fname));
612630
goto cleanup;
613631
}
614632
if (ret > 0) { /* ret == 1 if symlink could not be set */
615-
updated &= ~UPDATED_TIMES;
633+
updated &= ~(UPDATED_MTIME|UPDATED_ATIME);
616634
file->flags |= FLAG_TIME_FAILED;
617635
}
618636
}
619-
#ifdef SUPPORT_CRTIMES
620-
if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
621-
time_t file_crtime = F_CRTIME(file);
622-
if (sxp->crtime == 0)
623-
sxp->crtime = get_create_time(fname, &sxp->st);
624-
if (!same_time(sxp->crtime, 0L, file_crtime, 0L)
625-
&& set_create_time(fname, file_crtime) == 0)
626-
updated = 1;
627-
}
628-
#endif
629637

630638
#ifdef SUPPORT_ACLS
631639
/* It's OK to call set_acl() now, even for a dir, as the generator

‎syscall.c

+24-16
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,10 @@ int do_chmod(const char *path, mode_t mode)
233233
{
234234
static int switch_step = 0;
235235
int code;
236+
236237
if (dry_run) return 0;
237238
RETURN_ERROR_IF_RO_OR_LO;
239+
238240
switch (switch_step) {
239241
#ifdef HAVE_LCHMOD
240242
case 0:
@@ -415,7 +417,26 @@ int do_setattrlist_times(const char *path, STRUCT_STAT *stp)
415417
attrList.commonattr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME;
416418
return setattrlist(path, &attrList, ts, sizeof ts, FSOPT_NOFOLLOW);
417419
}
420+
421+
#ifdef SUPPORT_CRTIMES
422+
int do_setattrlist_crtime(const char *path, time_t crtime)
423+
{
424+
struct attrlist attrList;
425+
struct timespec ts;
426+
427+
if (dry_run) return 0;
428+
RETURN_ERROR_IF_RO_OR_LO;
429+
430+
ts.tv_sec = crtime;
431+
ts.tv_nsec = 0;
432+
433+
memset(&attrList, 0, sizeof attrList);
434+
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
435+
attrList.commonattr = ATTR_CMN_CRTIME;
436+
return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
437+
}
418438
#endif
439+
#endif /* HAVE_SETATTRLIST */
419440

420441
#ifdef SUPPORT_CRTIMES
421442
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)
439460
#endif
440461
}
441462

442-
int set_create_time(const char *path, time_t crtime)
463+
#if defined __CYGWIN__
464+
int do_SetFileTime(const char *path, time_t crtime)
443465
{
444466
if (dry_run) return 0;
445467
RETURN_ERROR_IF_RO_OR_LO;
446468

447-
{
448-
#ifdef HAVE_GETATTRLIST
449-
struct attrlist attrList;
450-
struct timespec ts;
451-
452-
ts.tv_sec = crtime;
453-
ts.tv_nsec = 0;
454-
455-
memset(&attrList, 0, sizeof attrList);
456-
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
457-
attrList.commonattr = ATTR_CMN_CRTIME;
458-
return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
459-
#elif defined __CYGWIN__
460469
int cnt = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
461470
if (cnt == 0)
462471
return -1;
@@ -476,9 +485,8 @@ int set_create_time(const char *path, time_t crtime)
476485
int ok = SetFileTime(handle, &birth_time, NULL, NULL);
477486
CloseHandle(handle);
478487
return ok ? 0 : -1;
479-
#endif
480-
}
481488
}
489+
#endif
482490
#endif /* SUPPORT_CRTIMES */
483491

484492
#ifdef HAVE_UTIMENSAT

0 commit comments

Comments
 (0)
Please sign in to comment.