diff options
author | Ondrej Oprala <ooprala@redhat.com> | 2012-08-07 16:56:52 +0200 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2012-09-28 12:21:02 +0200 |
commit | 24ebca61a3a0f10d6cd2800b188b3c034d1c4755 (patch) | |
tree | dfb6ffe8a3e1447432b9310a93f2785d787bcfb8 | |
parent | 64be8b40f457f6480f9e79777d98afce40469786 (diff) | |
download | coreutils-24ebca61a3a0f10d6cd2800b188b3c034d1c4755.tar.xz |
cp: fix the --no-preserve=mode option
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.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | src/copy.c | 10 | ||||
-rw-r--r-- | src/copy.h | 1 | ||||
-rw-r--r-- | src/cp.c | 3 | ||||
-rw-r--r-- | src/install.c | 1 | ||||
-rw-r--r-- | src/mv.c | 1 | ||||
-rwxr-xr-x | tests/cp/link-preserve.sh | 2 | ||||
-rwxr-xr-x | tests/cp/preserve-mode.sh | 54 | ||||
-rw-r--r-- | tests/local.mk | 1 |
10 files changed, 75 insertions, 4 deletions
@@ -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 @@ -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 diff --git a/src/copy.c b/src/copy.c index 2558fea14..16aed036d 100644 --- a/src/copy.c +++ b/src/copy.c @@ -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) diff --git a/src/copy.h b/src/copy.h index d70c09ea8..440d3bb24 100644 --- a/src/copy.h +++ b/src/copy.h @@ -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 @@ -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; diff --git a/src/install.c b/src/install.c index 854436aa3..8ea549135 100644 --- a/src/install.c +++ b/src/install.c @@ -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; @@ -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; diff --git a/tests/cp/link-preserve.sh b/tests/cp/link-preserve.sh index 0c75d305e..bb3b2447e 100755 --- a/tests/cp/link-preserve.sh +++ b/tests/cp/link-preserve.sh @@ -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 index 000000000..dc97cbaa0 --- /dev/null +++ b/tests/cp/preserve-mode.sh @@ -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 diff --git a/tests/local.mk b/tests/local.mk index 55700b532..0b6d576f8 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -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 \ |