diff options
author | Jim Meyering <jim@meyering.net> | 2006-02-04 10:49:21 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-02-04 10:49:21 +0000 |
commit | 130dd0656dc19c9b985b8e468dd29f687429d221 (patch) | |
tree | 03fcd6439a344ed4985f3e658a3ea5296e154bf4 /src | |
parent | ee84ffc69595708458036f19b28a290ccbbce241 (diff) | |
download | coreutils-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.c | 59 |
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) |