summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2007-11-15 13:04:13 +0100
committerJim Meyering <meyering@redhat.com>2007-11-15 13:04:13 +0100
commit2ed532618f1df9efa39b94bb2507319f48b650cf (patch)
tree32eac46bd8e82cb3f91ced3cf3a157e78cd175a0 /src
parent47a46c844c712f24c5f226743227ae85760f9def (diff)
downloadcoreutils-2ed532618f1df9efa39b94bb2507319f48b650cf.tar.xz
Avoid misbehavior of a cross-device "mv" or "install".
Those programs must not dereference a destination symlink. * src/copy.c (copy_reg): Don't treat a dangling destination symlink differently in move mode. In move mode, the only way the added O_EXCL can cause failure is when some other process has recreated the file this code unlinked a few instructions before.
Diffstat (limited to 'src')
-rw-r--r--src/copy.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/copy.c b/src/copy.c
index e1cd5fa21..1a265e3c2 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -371,8 +371,9 @@ copy_reg (char const *src_name, char const *dst_name,
the above open fails with EEXIST. If that happens, and
lstat'ing the DST_NAME shows that it is a symlink, repeat
the open call, but this time with the name of the final,
- missing directory entry. */
- if (dest_desc < 0 && dest_errno == EEXIST)
+ missing directory entry. All of this is relevant only for
+ cp, i.e., not in move_mode. */
+ if (dest_desc < 0 && dest_errno == EEXIST && ! x->move_mode)
{
struct stat dangling_link_sb;
if (lstat (dst_name, &dangling_link_sb) == 0