[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#31364: cp -rfs: Fails to overwrite a symlink when it is on a differe
From: |
Illia Bobyr |
Subject: |
bug#31364: cp -rfs: Fails to overwrite a symlink when it is on a different device |
Date: |
Fri, 04 May 2018 23:37:55 +0000 |
Hello,
I have found a bug in "cp -rfs".
Steps to reproduce:
1. Given "path1" and "path2" are on different devices.
2. $ touch "path1/file"
3. $ cd path2/; ln -s path1/file
4. $ cp --symbolic-link --force --recursive path1/file .
Expected:
The link is overwritten with an exact copy.
Actual result:
cp shows an error:
cp: 'path1/file' and './file' are the same file
This bug was introduced in
http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=376967889ed7ed561e46ff6d88a66779db62737a
Specifically this hunk:
diff --git a/src/copy.c b/src/copy.c
index e3832c2..9dbd536 100644
--- a/src/copy.c
<http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c?id=2f69dba5df8caaf9eda658c1808b1379e9949f22>
+++ b/src/copy.c
<http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c?id=376967889ed7ed561e46ff6d88a66779db62737a>
@@ -46,6 +46,7 @@
#include "file-set.h"
#include "filemode.h"
#include "filenamecat.h"
+#include "force-link.h"
#include "full-write.h"
#include "hash.h"
#include "hash-triple.h"
@@ -1623,11 +1624,13 @@ same_file_ok (char const *src_name, struct stat
const *src_sb,
}
}
- /* It's ok to remove a destination symlink. But that works only when we
- unlink before opening the destination and when the source and destination
- files are on the same partition. */
- if (x->unlink_dest_before_opening
- && S_ISLNK (dst_sb_link->st_mode))
+ /* It's ok to remove a destination symlink. But that works only
+ when creating symbolic links, or when the source and destination
+ are on the same file system and when creating hard links or when
+ unlinking before opening the destination. */
+ if (x->symbolic_link
+ || ((x->hard_link || x->unlink_dest_before_opening)
+ && S_ISLNK (dst_sb_link->st_mode)))
return dst_sb_link->st_dev == src_sb_link->st_dev;
if (x->dereference == DEREF_NEVER)
Two patches that fix the issue are attached.
They are against the current master in
https://github.com/coreutils/coreutils
The changes are also here:
https://github.com/coreutils/coreutils/compare/master...ilya-bobyr:master
Thank you, Illia Bobyr
0002-cp-Overwrite-symlinks-on-another-device.patch
Description: Text Data
0001-cp-No-dup-check-for-unlink_dest_after_failed_open.patch
Description: Text Data
- bug#31364: cp -rfs: Fails to overwrite a symlink when it is on a different device,
Illia Bobyr <=