bug-coreutils
[Top][All Lists]
Advanced

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

moving timestamp preservation to the last step in copy_internal() / copy


From: Mike Frysinger
Subject: moving timestamp preservation to the last step in copy_internal() / copy_reg()
Date: Mon, 8 May 2006 22:55:25 -0400
User-agent: KMail/1.9.1

a user pointed out that `cp -p` failed to preserve times on a nfs mount:
http://bugs.gentoo.org/132673

this is because changing ownership on a nfs mount updates the ctimes:
touch foo
# stat foo
  File: `foo'
  Size: 0               Blocks: 0          IO Block: 16384  regular empty file
Device: eh/14d  Inode: 584188      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (  250/ portage)
Access: 2006-05-08 22:34:13.621879904 -0400
Modify: 2006-05-08 22:34:13.621879904 -0400
Change: 2006-05-08 22:34:13.621879904 -0400
# chown 1 foo
# stat foo
  File: `foo'
  Size: 0               Blocks: 0          IO Block: 16384  regular empty file
Device: eh/14d  Inode: 584188      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    1/     bin)   Gid: (  250/ portage)
Access: 2006-05-08 22:34:13.621879904 -0400
Modify: 2006-05-08 22:34:13.621879904 -0400
Change: 2006-05-08 22:34:21.628662688 -0400

i dont know if POSIX has an opinion on the order of operations, but SUSv3 
doesnt care:
http://www.opengroup.org/onlinepubs/009695399/utilities/cp.html
...
-p Duplicate the following characteristics of each source file in the 
corresponding destination file:
...
The order in which the preceding characteristics are duplicated is 
unspecified.

so would there be any real detrimental effects with the attached patch ? 
clearing the setid bits wouldnt be affected by changing of timestamps, so 
doing it after the chown() should be fine ...
-mike
2006-05-08  Mike Frysinger  <address@hidden>

        src/copy.c (copy_reg): Move preserve_timestamps logic last.
        (copy_internal): Likewise.

--- src/copy.c
+++ src/copy.c
@@ -483,23 +483,6 @@ 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;
-             goto close_src_and_dst_desc;
-           }
-       }
-    }
-
   if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb))
     {
       if (! set_owner (x, dst_name, dest_desc, src_sb->st_uid, src_sb->st_gid))
@@ -523,6 +506,23 @@ copy_reg (char const *src_name, char con
        return_val = false;
     }
 
+  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;
+             goto close_src_and_dst_desc;
+           }
+       }
+    }
+
 close_src_and_dst_desc:
   if (close (dest_desc) < 0)
     {
@@ -1727,24 +1727,9 @@ copy_internal (char const *src_name, cha
      the destination must not be removed.
      FIXME: implement the above. */
 
-  /* Adjust the times (and if possible, ownership) for the copy.
-     chown turns off set[ug]id bits for non-root,
+  /* chown turns off set[ug]id bits for non-root,
      so do the chmod last.  */
 
-  if (x->preserve_timestamps)
-    {
-      struct timespec timespec[2];
-      timespec[0] = get_stat_atime (&src_sb);
-      timespec[1] = get_stat_mtime (&src_sb);
-
-      if (utimens (dst_name, timespec) != 0)
-       {
-         error (0, errno, _("preserving times for %s"), quote (dst_name));
-         if (x->require_preserve)
-           return false;
-       }
-    }
-
   /* Avoid calling chown if we know it's not necessary.  */
   if (x->preserve_ownership
       && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
@@ -1777,6 +1762,21 @@ copy_internal (char const *src_name, cha
        }
     }
 
+  /* Adjust the times (and if possible, ownership) for the copy.  */
+  if (x->preserve_timestamps)
+    {
+      struct timespec timespec[2];
+      timespec[0] = get_stat_atime (&src_sb);
+      timespec[1] = get_stat_mtime (&src_sb);
+
+      if (utimens (dst_name, timespec) != 0)
+       {
+         error (0, errno, _("preserving times for %s"), quote (dst_name));
+         if (x->require_preserve)
+           return false;
+       }
+    }
+
   return delayed_ok;
 
 un_backup:

reply via email to

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