bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

utimes-related improvements for cp, mv, install


From: Paul Eggert
Subject: utimes-related improvements for cp, mv, install
Date: Fri, 23 Sep 2005 13:53:37 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

I noticed that cp, mv, and install were using utimes rather than
futimes.  It's more efficient to operate through the file descriptor
if possible, and it also avoids some race conditions.

Also, install was invoking utimes twice on the resulting file; that
isn't needed unless the -s option is also specified.

I installed this:

2005-09-23  Paul Eggert  <address@hidden>

        * src/copy.c (copy_reg): Preserve time stamps if
        x->preserve_timestamps is set, using futimens so that
        we needn't resolve the path again.
        (copy_internal): Don't preserve time stamps if copy_reg did it
        already.
        * src/install.c (change_timestamps): First arg is source
        struct stat, not file name.  All uses changed.
        (install_file_in_file): Stat the source file.
        Don't try to change time stamps if copy_file did it.

--- src/copy.c  16 Sep 2005 07:50:33 -0000      1.188
+++ src/copy.c  23 Sep 2005 20:37:59 -0000
@@ -403,6 +403,20 @@ copy_reg (char const *src_name, char con
        }
     }
 
+  if (x->preserve_timestamps)
+    {
+      struct timespec timespec[2];
+      timespec[0] = get_stat_atime (src_sb);
+      timespec[1] = get_stat_mtime (src_sb);
+
+      if (futimens (dest_desc, dst_name, timespec) != 0)
+       {
+         error (0, errno, _("preserving times for %s"), quote (dst_name));
+         if (x->require_preserve)
+           return_val = false;
+       }
+    }
+
 close_src_and_dst_desc:
   if (close (dest_desc) < 0)
     {
@@ -1564,10 +1578,9 @@ copy_internal (char const *src_name, cha
      chown turns off set[ug]id bits for non-root,
      so do the chmod last.  */
 
-  if (x->preserve_timestamps)
+  if (!copied_as_regular && x->preserve_timestamps)
     {
       struct timespec timespec[2];
-
       timespec[0] = get_stat_atime (&src_sb);
       timespec[1] = get_stat_mtime (&src_sb);
 
--- src/install.c       16 Sep 2005 07:50:33 -0000      1.187
+++ src/install.c       23 Sep 2005 20:50:49 -0000      1.189
@@ -65,7 +65,7 @@
 /* Number of bytes of a file to copy at a time. */
 #define READ_SIZE (32 * 1024)
 
-static bool change_timestamps (const char *from, const char *to);
+static bool change_timestamps (struct stat const *from_sb, char const *to);
 static bool change_attributes (char const *name);
 static bool copy_file (const char *from, const char *to,
                       const struct cp_options *x);
@@ -439,14 +439,20 @@ static bool
 install_file_in_file (const char *from, const char *to,
                      const struct cp_options *x)
 {
+  struct stat from_sb;
+  if (x->preserve_timestamps && stat (from, &from_sb) != 0)
+    {
+      error (0, errno, _("cannot stat %s"), quote (from));
+      return false;
+    }
   if (! copy_file (from, to, x))
     return false;
   if (strip_files)
     strip (to);
   if (! change_attributes (to))
     return false;
-  if (x->preserve_timestamps)
-    return change_timestamps (from, to);
+  if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode)))
+    return change_timestamps (&from_sb, to);
   return true;
 }
 
@@ -526,19 +532,12 @@ change_attributes (char const *name)
    Return true if successful.  */
 
 static bool
-change_timestamps (const char *from, const char *to)
+change_timestamps (struct stat const *from_sb, char const *to)
 {
-  struct stat stb;
   struct timespec timespec[2];
+  timespec[0] = get_stat_atime (from_sb);
+  timespec[1] = get_stat_mtime (from_sb);
 
-  if (stat (from, &stb))
-    {
-      error (0, errno, _("cannot obtain time stamps for %s"), quote (from));
-      return false;
-    }
-
-  timespec[0] = get_stat_atime (&stb);
-  timespec[1] = get_stat_mtime (&stb);
   if (utimens (to, timespec))
     {
       error (0, errno, _("cannot set time stamps for %s"), quote (to));




reply via email to

[Prev in Thread] Current Thread [Next in Thread]