]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
cp: fix the --no-preserve=mode option
authorOndrej Oprala <ooprala@redhat.com>
Tue, 7 Aug 2012 14:56:52 +0000 (16:56 +0200)
committerJim Meyering <meyering@redhat.com>
Fri, 28 Sep 2012 10:21:02 +0000 (12:21 +0200)
The --no-preserve=mode option did not do what its name implies:
it would mistakenly preserve permission mode bits.
* NEWS: Mention the fix.
* TODO: Remove an entry.
* src/copy.c (copy_reg): Add a condition to properly
handle the --no-preserve=mode option for files
(copy_internal): Add a condition to properly handle the
--no-preserve=mode option for directories.
* src/copy.h (struct cp_options): Add a new boolean.
* src/cp.c (cp_option_init,decode_preserve_arg): Set the
new boolean value according to specified options.
* src/install.c (struct cp_options): Initialize the new boolean.
* src/mv.c (struct cp_options): Initialize the new boolean.
* tests/cp/preserve-mode.sh: Add a new test.
* tests/cp/link-preserve.sh (-a --no-preserve=mode): Adjust the
expected perms: now, --no-preserve=mode overrides the --preserve=mode
that is inherent in -a, as it should.
* tests/local.mk: Add the new test to the list.

NEWS
TODO
src/copy.c
src/copy.h
src/cp.c
src/install.c
src/mv.c
tests/cp/link-preserve.sh
tests/cp/preserve-mode.sh [new file with mode: 0755]
tests/local.mk

diff --git a/NEWS b/NEWS
index edc436c1b4d14b01a580531e4dc5fa842ebe0109..25f1a279b4fef3155222e0f6b13b585957de706e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  cp --no-preserve=mode now no longer preserves the original file's
+  permissions but correctly sets mode specified by 0666 & ~umask
+
   du no longer emits a "disk-corrupted"-style diagnostic when it detects
   a directory cycle that is due to a bind-mounted directory.  Instead,
   it detects this precise type of cycle, diagnoses it as such and
diff --git a/TODO b/TODO
index cd434e5498995dd47b969c9d21d10e7620b73338..2dcaf0864114926995fecc5cf3e53c775e07e6cb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -47,9 +47,6 @@ doc/coreutils.texi:
 
 ls: add --format=FORMAT option that controls how each line is printed.
 
-cp --no-preserve=X should not attempt to preserve attribute X
-  reported by Andreas Schwab
-
 copy.c: Address the FIXME-maybe comment in copy_internal.
 And once that's done, add an exclusion so that 'cp --link'
 no longer incurs the overhead of saving src. dev/ino and dest. filename
index 2558fea14d76d3ed9fc54814f4759e7f82d29e9f..16aed036d278bcd80294fff631456dd9466a2d14 100644 (file)
@@ -1151,6 +1151,11 @@ preserve_metadata:
       if (set_acl (dst_name, dest_desc, x->mode) != 0)
         return_val = false;
     }
+  else if (x->explicit_no_preserve_mode)
+    {
+      set_acl (dst_name, dest_desc, 0666 & ~cached_umask ());
+      return_val = false;
+    }
   else if (omitted_permissions)
     {
       omitted_permissions &= ~ cached_umask ();
@@ -2570,6 +2575,11 @@ copy_internal (char const *src_name, char const *dst_name,
       if (set_acl (dst_name, -1, x->mode) != 0)
         return false;
     }
+  else if (x->explicit_no_preserve_mode)
+    {
+      if (set_acl (dst_name, -1, 0777 & ~cached_umask ()) != 0)
+        return false;
+    }
   else
     {
       if (omitted_permissions)
index d70c09ea88fe7bb3ee4f39673b6a57146af49a66..440d3bb244a5d809b980de8682f4f8f11f0d06cf 100644 (file)
@@ -157,6 +157,7 @@ struct cp_options
   bool preserve_ownership;
   bool preserve_mode;
   bool preserve_timestamps;
+  bool explicit_no_preserve_mode;
 
   /* Enabled for mv, and for cp by the --preserve=links option.
      If true, attempt to preserve in the destination files any
index 6649af2e96305bc3825bdc89666546974e435d8f..61b31afdc919662514946034af5440c706d2894f 100644 (file)
--- a/src/cp.c
+++ b/src/cp.c
@@ -783,6 +783,7 @@ cp_option_init (struct cp_options *x)
   x->preserve_links = false;
   x->preserve_mode = false;
   x->preserve_timestamps = false;
+  x->explicit_no_preserve_mode = false;
   x->preserve_security_context = false;
   x->require_preserve_context = false;
   x->preserve_xattr = false;
@@ -860,6 +861,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
         {
         case PRESERVE_MODE:
           x->preserve_mode = on_off;
+          x->explicit_no_preserve_mode = !on_off;
           break;
 
         case PRESERVE_TIMESTAMPS:
@@ -889,6 +891,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
           x->preserve_timestamps = on_off;
           x->preserve_ownership = on_off;
           x->preserve_links = on_off;
+          x->explicit_no_preserve_mode = !on_off;
           if (selinux_enabled)
             x->preserve_security_context = on_off;
           x->preserve_xattr = on_off;
index 854436aa3dab7dd00eb4b950834963eaa8bd5135..8ea549135b268956a9e504952654f4a7cea9a57e 100644 (file)
@@ -275,6 +275,7 @@ cp_option_init (struct cp_options *x)
   x->preserve_links = false;
   x->preserve_mode = false;
   x->preserve_timestamps = false;
+  x->explicit_no_preserve_mode = false;
   x->reduce_diagnostics=false;
   x->data_copy_required = true;
   x->require_preserve = false;
index 4f5708eb252bfdd4980c80852e3eafcf3bfa2ddf..5b08fdd582ac7b15f684476e2b4e267d2a7e90be 100644 (file)
--- a/src/mv.c
+++ b/src/mv.c
@@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x)
   x->preserve_links = true;
   x->preserve_mode = true;
   x->preserve_timestamps = true;
+  x->explicit_no_preserve_mode= false;
   x->preserve_security_context = selinux_enabled;
   x->reduce_diagnostics = false;
   x->data_copy_required = true;
index 0c75d305edb518254b6c452d7cabd6da7f2f0079..bb3b2447e423c26894ce73230bd3729b3cfb8f56 100755 (executable)
@@ -84,7 +84,7 @@ touch a; chmod 731 a
 umask 077
 cp -a --no-preserve=mode a b
 mode=$(ls -l b|cut -b-10)
-test "$mode" = "-rwx------" || fail=1
+test "$mode" = "-rw-------" || fail=1
 umask 022
 # --------------------------------------
 
diff --git a/tests/cp/preserve-mode.sh b/tests/cp/preserve-mode.sh
new file mode 100755 (executable)
index 0000000..dc97cba
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+# ensure that cp's --no-preserve=mode works correctly
+
+# Copyright (C) 2002-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=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ cp
+
+rm -f a b c
+umask 0022
+touch a
+touch b
+chmod 600 b
+
+#regular file test
+cp --no-preserve=mode b c
+mode_a=$(ls -l a | gawk '{print $1}')
+mode_c=$(ls -l c | gawk '{print $1}')
+test "$mode_a" = "$mode_c" || fail=1
+
+rm -rf d1 d2 d3
+mkdir d1 d2
+chmod 705 d2
+
+#directory test
+cp --no-preserve=mode -r d2 d3
+mode_d1=$(ls -l d1 | gawk '{print $1}')
+mode_d3=$(ls -l d3 | gawk '{print $1}')
+test "$mode_d1" = "$mode_d3" || fail=1
+
+rm -f a b c
+touch a
+chmod 600 a
+
+#contradicting options test
+cp --no-preserve=mode --preserve=all a b
+mode_a=$(ls -l a | gawk '{print $1}')
+mode_b=$(ls -l b | gawk '{print $1}')
+test "$mode_a" = "$mode_b" || fail=1
+
+Exit $fail
index 55700b532cdee3a2367ebd03059eaad00e812287..0b6d576f8a84ac7eeb7223a06c79608e221fe8f9 100644 (file)
@@ -434,6 +434,7 @@ all_tests =                                 \
   tests/cp/perm.sh                             \
   tests/cp/preserve-2.sh                       \
   tests/cp/preserve-link.sh                    \
+  tests/cp/preserve-mode.sh                    \
   tests/cp/preserve-slink-time.sh              \
   tests/cp/proc-short-read.sh                  \
   tests/cp/proc-zero-len.sh                    \