On 25/07/11 17:26, Pádraig Brady wrote:
> Actually I'm wondering now whether the new code
> should be unconditionally replacing the dest?
> What if the dest is a separate newer file?
> I.E. I think the following amended test should pass?
> Also what about backups if the separate file is older?
Well backups take a different path, as do
older or non existing destination paths.
So how about this change to just remove
the new create_hard_link: call and beef up the test?
cheers,
Pádraig.
diff --git a/src/copy.c b/src/copy.c
index df8b1db..d6a0d1a 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1633,11 +1633,11 @@ copy_internal (char const *src_name, char const *dst_name,
this src/dest pair, in case this source file is
hard-linked to another one. In that case, we'll use
the mapping information to link the corresponding
- destination names. */
- earlier_file = remember_copied (dst_name, src_sb.st_ino,
- src_sb.st_dev);
- if (earlier_file)
- goto create_hard_link;
+ destination names. Note we don't hard link DST_NAME
+ here, because it may be a separate file with newer
+ or same timestamp. If it's older than SRC_NAME,
+ then this path is not taken. */
+ remember_copied (dst_name, src_sb.st_ino, src_sb.st_dev);
return true;
}
@@ -1959,7 +1959,6 @@ copy_internal (char const *src_name, char const *dst_name,
}
else
{
- create_hard_link:;
/* We want to guarantee that symlinks are not followed. */
bool link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD,
dst_name, 0) != 0);
diff --git a/tests/cp/preserve-link b/tests/cp/preserve-link
index d0da873..6beae02 100755
--- a/tests/cp/preserve-link
+++ b/tests/cp/preserve-link
@@ -28,13 +28,31 @@ same_inode()
mkdir -p s t/s || framework_failure_
touch s/f t/s/f || framework_failure_
+
+# a non existing link must be linked in the dest tree
ln s/f s/link || framework_failure_
+# an existing link must be updated
+ln s/f s/linke || framework_failure_
+ln t/s/f t/s/linke || framework_failure_
+
+# an updated older file must be overwritten
+ln s/f s/fileo || framework_failure_
+touch -d "-1 hour" t/s/fileo || framework_failure_
+
+# an updated non linked file must not be overwritten
+ln s/f s/fileu || framework_failure_
+touch -d "+1 hour" t/s/fileu || framework_failure_
+
# This must create a hard link, t/s/link, to the existing file, t/s/f.
# With cp from coreutils-8.12 and prior, it would mistakenly copy
# the file rather than creating the link.
+touch -d "+1 hour" t/s/f || framework_failure_
cp -au s t || fail=1
same_inode t/s/f t/s/link || fail=1
+same_inode t/s/f t/s/linke || fail=1
+same_inode t/s/f t/s/fileo || fail=1
+same_inode t/s/f t/s/fileu && fail=1
Exit $fail