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.
This commit is contained in:
Paul Eggert
2010-09-16 10:46:27 -07:00
parent ecbcb7b6d7
commit d945888643
4 changed files with 14 additions and 8 deletions

View File

@@ -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. */

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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. */