From d9458886432a92230e432e8e8492703c7afb8272 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 16 Sep 2010 10:46:27 -0700 Subject: [PATCH] tar: another --atime-preserve race fix * src/common.h (set_file_atime): Add parentfd arg. * src/compare.c (diff_file): Use it. * src/create.c (dump_file0): Likewise. This closes yet another race condition with symbolic links. * src/misc.c (set_file_atime): Add parentfd arg. --- src/common.h | 4 ++-- src/compare.c | 4 +++- src/create.c | 4 +++- src/misc.c | 10 ++++++---- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/common.h b/src/common.h index 8bd8640..e0d8eb7 100644 --- a/src/common.h +++ b/src/common.h @@ -638,8 +638,8 @@ pid_t xfork (void); void xpipe (int fd[2]); void *page_aligned_alloc (void **ptr, size_t size); -int set_file_atime (int fd, char const *file, struct timespec atime, - int atflag); +int set_file_atime (int fd, int parentfd, char const *file, + struct timespec atime, int atflag); /* Module names.c. */ diff --git a/src/compare.c b/src/compare.c index 6a873d7..204c5dc 100644 --- a/src/compare.c +++ b/src/compare.c @@ -244,7 +244,9 @@ diff_file (void) if (atime_preserve_option == replace_atime_preserve) { struct timespec atime = get_stat_atime (&stat_data); - if (set_file_atime (diff_handle, file_name, atime, 0) != 0) + if (set_file_atime (diff_handle, AT_FDCWD, file_name, + atime, 0) + != 0) utime_error (file_name); } diff --git a/src/create.c b/src/create.c index 6eedb2e..0d22e96 100644 --- a/src/create.c +++ b/src/create.c @@ -1793,7 +1793,9 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p) set_exit_status (TAREXIT_DIFFERS); } else if (atime_preserve_option == replace_atime_preserve - && set_file_atime (fd, p, st->atime, fstatat_flags) != 0) + && (set_file_atime (fd, parentfd, name, + st->atime, fstatat_flags) + != 0)) utime_error (p); } diff --git a/src/misc.c b/src/misc.c index 1cf0c3b..64b1b2b 100644 --- a/src/misc.c +++ b/src/misc.c @@ -628,15 +628,17 @@ fd_utimensat (int fd, int parentfd, char const *file, return utimensat (parentfd, file, ts, atflag); } -/* Set FD's (i.e., FILE's) access time to ATIME. - ATFLAG controls symbolic-link following, in the style of openat. */ +/* Set FD's (i.e., assuming the working directory is PARENTFD, FILE's) + access time to ATIME. ATFLAG controls symbolic-link following, in + the style of openat. */ int -set_file_atime (int fd, char const *file, struct timespec atime, int atflag) +set_file_atime (int fd, int parentfd, char const *file, struct timespec atime, + int atflag) { struct timespec ts[2]; ts[0] = atime; ts[1].tv_nsec = UTIME_OMIT; - return fd_utimensat (fd, AT_FDCWD, file, ts, atflag); + return fd_utimensat (fd, parentfd, file, ts, atflag); } /* A description of a working directory. */ -- 2.45.2