]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
cp: change --attributes-only to not truncate existing files
authorPádraig Brady <P@draigBrady.com>
Thu, 12 Apr 2012 11:47:30 +0000 (12:47 +0100)
committerPádraig Brady <P@draigBrady.com>
Thu, 12 Apr 2012 17:35:17 +0000 (18:35 +0100)
* src/copy.c (copy_reg): Don't truncate an existing file,
to support copying attributes between existing files.
The original use case only considered creating new files,
and it would be a very unusual use case to be relying
on the truncating behavior.
* doc/coreutils.texi (cp invocation): Mention the non
truncating behavior.
* tests/cp/attr-existing: A new test to ensure O_TRUNC skipped.
* tests/Makefile.am: Reference the new test.
* NEWS: Mention the change in behavior.

NEWS
doc/coreutils.texi
src/copy.c
tests/Makefile.am
tests/cp/attr-existing [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index c8d2bbcf07ee1482b4dbb9a10e12203d37744b0a..42df465dcb955684de4f91b78e0253f0854adeb0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Changes in behavior
+
+  cp --attributes-only no longer truncates any existing destination file,
+  allowing for more general copying of attributes from one file to another.
+
 
 * Noteworthy changes in release 8.16 (2012-03-26) [stable]
 
index 510abb9035e730cb7ac604a2005340cb15140842..1fbf05116852f6014445efd633c0e2dfb3dff98d 100644 (file)
@@ -7649,9 +7649,9 @@ Equivalent to @option{-dR --preserve=all} with the reduced diagnostics.
 
 @itemx --attributes-only
 @opindex --attributes-only
-Preserve the specified attributes of the original files in the copy,
-but do not copy any data.  See the @option{--preserve} option for
-controlling which attributes to copy.
+Copy only the specified attributes of the source file to the destination.
+If the destination already exists, do not alter its contents.
+See the @option{--preserve} option for controlling which attributes to copy.
 
 @item -b
 @itemx @w{@kbd{--backup}[=@var{method}]}
index f63a726961b0f2153d5d51f9b5114e7d6b403855..414fbe0e8ccd469acf139589e90b4036ec373557 100644 (file)
@@ -826,7 +826,9 @@ copy_reg (char const *src_name, char const *dst_name,
      by the specs for both cp and mv.  */
   if (! *new_dst)
     {
-      dest_desc = open (dst_name, O_WRONLY | O_TRUNC | O_BINARY);
+      int open_flags =
+        O_WRONLY | O_BINARY | (x->data_copy_required ? O_TRUNC : 0);
+      dest_desc = open (dst_name, open_flags);
       dest_errno = errno;
 
       /* When using cp --preserve=context to copy to an existing destination,
index 011051aa5e317bd3515be58bc2ec294d245aeef5..4d73a92b536318a683f47303011f4a3e150c4f82 100644 (file)
@@ -320,6 +320,7 @@ TESTS =                                             \
   chown/separator                              \
   cp/abuse                                     \
   cp/acl                                       \
+  cp/attr-existing                             \
   cp/backup-1                                  \
   cp/backup-dir                                        \
   cp/backup-is-src                             \
diff --git a/tests/cp/attr-existing b/tests/cp/attr-existing
new file mode 100755 (executable)
index 0000000..9cf0ffc
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+# Make sure cp --attributes-only doesn't truncate existing data
+
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+print_ver_ cp
+
+printf '1' > file1
+printf '2' > file2
+printf '2' > file2.exp
+
+cp --attributes-only file1 file2 || fail=1
+cmp file2 file2.exp || fail=1
+
+Exit $fail