summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-02-04 10:49:21 +0000
committerJim Meyering <jim@meyering.net>2006-02-04 10:49:21 +0000
commit130dd0656dc19c9b985b8e468dd29f687429d221 (patch)
tree03fcd6439a344ed4985f3e658a3ea5296e154bf4 /src
parentee84ffc69595708458036f19b28a290ccbbce241 (diff)
downloadcoreutils-130dd0656dc19c9b985b8e468dd29f687429d221.tar.xz
(copy_internal): cp -RL no longer fails when encountering
the same directory more than once in the hierarchy beneath a single command-line argument. That is legitimate, e.g. when there are two or more symbolic links, each pointing to some directory that would not otherwise be copied. Reported by Christophe LYON.
Diffstat (limited to 'src')
-rw-r--r--src/copy.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/copy.c b/src/copy.c
index ba8c4e189..8a9f7d101 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1302,40 +1302,49 @@ copy_internal (char const *src_name, char const *dst_name,
quote_n (0, top_level_src_name),
quote_n (1, top_level_dst_name));
*copy_into_self = true;
+ goto un_backup;
+ }
+ else if (x->dereference == DEREF_ALWAYS)
+ {
+ /* This happens when e.g., encountering a directory for the
+ second or subsequent time via symlinks when cp is invoked
+ with -R and -L. E.g.,
+ rm -rf a b c d; mkdir a b c d; ln -s ../c a; ln -s ../c b;
+ cp -RL a b d
+ */
}
else
{
error (0, 0, _("will not create hard link %s to directory %s"),
quote_n (0, dst_name), quote_n (1, earlier_file));
+ goto un_backup;
}
-
- goto un_backup;
}
+ else
+ {
+ bool link_failed = (link (earlier_file, dst_name) != 0);
- {
- bool link_failed = (link (earlier_file, dst_name) != 0);
-
- /* If the link failed because of an existing destination,
- remove that file and then call link again. */
- if (link_failed && errno == EEXIST)
- {
- if (unlink (dst_name) != 0)
- {
- error (0, errno, _("cannot remove %s"), quote (dst_name));
- goto un_backup;
- }
- link_failed = (link (earlier_file, dst_name) != 0);
- }
-
- if (link_failed)
- {
- error (0, errno, _("cannot create hard link %s to %s"),
- quote_n (0, dst_name), quote_n (1, earlier_file));
- goto un_backup;
- }
+ /* If the link failed because of an existing destination,
+ remove that file and then call link again. */
+ if (link_failed && errno == EEXIST)
+ {
+ if (unlink (dst_name) != 0)
+ {
+ error (0, errno, _("cannot remove %s"), quote (dst_name));
+ goto un_backup;
+ }
+ link_failed = (link (earlier_file, dst_name) != 0);
+ }
- return true;
- }
+ if (link_failed)
+ {
+ error (0, errno, _("cannot create hard link %s to %s"),
+ quote_n (0, dst_name), quote_n (1, earlier_file));
+ goto un_backup;
+ }
+
+ return true;
+ }
}
if (x->move_mode)