summaryrefslogtreecommitdiff
path: root/system/coreutils/cp-dont-delete.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/coreutils/cp-dont-delete.patch')
-rw-r--r--system/coreutils/cp-dont-delete.patch72
1 files changed, 72 insertions, 0 deletions
diff --git a/system/coreutils/cp-dont-delete.patch b/system/coreutils/cp-dont-delete.patch
new file mode 100644
index 000000000..a60608952
--- /dev/null
+++ b/system/coreutils/cp-dont-delete.patch
@@ -0,0 +1,72 @@
+From 7b5f0fa47cd04c84975250d5b5da7c98e097e99f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
+Date: Wed, 1 Apr 2020 12:51:34 +0100
+Subject: cp: ensure --attributes-only doesn't remove files
+
+* src/copy.c (copy_internal): Ensure we don't unlink the destination
+unless explicitly requested.
+* tests/cp/attr-existing.sh: Add test cases.
+Fixes https://bugs.gnu.org/40352
+---
+ NEWS | 7 +++++++
+ src/copy.c | 9 +++++----
+ tests/cp/attr-existing.sh | 21 ++++++++++++++++++---
+ 3 files changed, 30 insertions(+), 7 deletions(-)
+
+diff --git a/src/copy.c b/src/copy.c
+index 6e5efc708..54601ce07 100644
+--- a/src/copy.c
++++ b/src/copy.c
+@@ -2211,10 +2211,11 @@ copy_internal (char const *src_name, char const *dst_name,
+ /* Never unlink dst_name when in move mode. */
+ && ! x->move_mode
+ && (x->unlink_dest_before_opening
+- || (x->preserve_links && 1 < dst_sb.st_nlink)
+- || (x->dereference == DEREF_NEVER
+- && ! S_ISREG (src_sb.st_mode))
+- ))
++ || (x->data_copy_required
++ && ((x->preserve_links && 1 < dst_sb.st_nlink)
++ || (x->dereference == DEREF_NEVER
++ && ! S_ISREG (src_sb.st_mode))))
++ ))
+ {
+ if (unlink (dst_name) != 0 && errno != ENOENT)
+ {
+diff --git a/tests/cp/attr-existing.sh b/tests/cp/attr-existing.sh
+index 59ce64183..14fc8445c 100755
+--- a/tests/cp/attr-existing.sh
++++ b/tests/cp/attr-existing.sh
+@@ -19,11 +19,26 @@
+ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+ print_ver_ cp
+
+-printf '1' > file1
+-printf '2' > file2
+-printf '2' > file2.exp
++printf '1' > file1 || framework_failure_
++printf '2' > file2 || framework_failure_
++printf '2' > file2.exp || framework_failure_
+
+ cp --attributes-only file1 file2 || fail=1
+ cmp file2 file2.exp || fail=1
+
++# coreutils v8.32 and before would remove destination files
++# if hardlinked or the source was not a regular file.
++ln file2 link2 || framework_failure_
++cp -a --attributes-only file1 file2 || fail=1
++cmp file2 file2.exp || fail=1
++
++ln -s file1 sym1 || framework_failure_
++returns_ 1 cp -a --attributes-only sym1 file2 || fail=1
++cmp file2 file2.exp || fail=1
++
++# One can still force removal though
++cp -a --remove-destination --attributes-only sym1 file2 || fail=1
++test -L file2 || fail=1
++cmp file1 file2 || fail=1
++
+ Exit $fail
+--
+cgit v1.2.1
+