Skip to content

Commit 51b3597

Browse files
committed
cp: Fix explicit preserve mode
1 parent b31ffda commit 51b3597

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/uu/cp/src/cp.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,8 +1692,9 @@ pub(crate) fn copy_attributes(
16921692
fs::symlink_metadata(source).map_err(|e| CpError::IoErrContext(e, context.to_owned()))?;
16931693

16941694
let is_preserve_required = matches!(options.attributes.mode, Preserve::Yes { required: true });
1695+
let is_explicit_true = matches!(options.attributes.mode, Preserve::No { explicit: true });
16951696

1696-
let mode = if !is_preserve_required && dest.is_dir() && is_dir_created {
1697+
let mode = if !is_preserve_required && !is_explicit_true && dest.is_dir() && is_dir_created {
16971698
Preserve::Yes { required: false }
16981699
} else {
16991700
options.attributes.mode
@@ -1744,7 +1745,7 @@ pub(crate) fn copy_attributes(
17441745
// permissions.
17451746
if !dest.is_symlink() {
17461747
let mut perms = source_metadata.permissions();
1747-
if is_dir_created && !is_preserve_required {
1748+
if is_dir_created && !is_preserve_required && !is_explicit_true {
17481749
let mode = handle_no_preserve_mode(options, perms.mode());
17491750
use uucore::mode::get_umask;
17501751
let mode = mode & !get_umask();

tests/by-util/test_cp.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7516,3 +7516,30 @@ fn test_cp_existing_perm_dir() {
75167516

75177517
assert_eq!(mode, 0o40700);
75187518
}
7519+
7520+
#[test]
7521+
#[cfg(not(target_os = "windows"))]
7522+
fn test_cp_gnu_preserve_mode() {
7523+
use std::io;
7524+
7525+
let scene = TestScenario::new(util_name!());
7526+
let at = &scene.fixtures;
7527+
7528+
scene.cmd("mkdir").arg("d1").succeeds();
7529+
scene.cmd("mkdir").arg("d2").succeeds();
7530+
scene.cmd("chmod").arg("705").arg("d2").succeeds();
7531+
7532+
scene
7533+
.ucmd()
7534+
.arg("--no-preserve=mode")
7535+
.arg("-r")
7536+
.arg("d2")
7537+
.arg("d3")
7538+
.set_stdout(io::stdout())
7539+
.succeeds();
7540+
7541+
let d1_mode = get_mode(at.plus("d1"));
7542+
let d3_mode = get_mode(at.plus("d3"));
7543+
7544+
assert_eq!(d1_mode, d3_mode);
7545+
}

0 commit comments

Comments
 (0)