Browse Source

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.
Paul Eggert 14 years ago
parent
commit
d945888643
4 changed files with 14 additions and 8 deletions
  1. 2 2
      src/common.h
  2. 3 1
      src/compare.c
  3. 3 1
      src/create.c
  4. 6 4
      src/misc.c

+ 2 - 2
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.  */
 

+ 3 - 1
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);
 		}
 

+ 3 - 1
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);
 	}
 

+ 6 - 4
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.  */