diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 2823b35b1a2..cfe662d7bf2 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -620,7 +620,7 @@ impl ChownExecutor { continue; } - ret = match wrap_chown( + ret |= match wrap_chown( path, &meta, self.dest_uid, diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index cc0727dd3eb..ede65956fce 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -640,3 +640,30 @@ fn test_chgrp_recursive_on_file() { current_gid ); } + +#[test] +fn test_chgrp_multiple_files_error_on_first_success_on_last() { + use std::os::unix::fs::PermissionsExt; + + let (at, mut ucmd) = at_and_ucmd!(); + + let current_gid = getegid(); + + at.mkdir("a_readonly_dir"); + at.mkdir("a_readonly_dir/subdir"); + at.touch("a_readonly_dir/subdir/file"); + at.touch("b_writable_file"); + + std::fs::set_permissions( + at.plus("a_readonly_dir/subdir"), + std::fs::Permissions::from_mode(0o000), + ) + .unwrap(); + + ucmd.arg("-R") + .arg(current_gid.to_string()) + .arg("a_readonly_dir") + .arg("b_writable_file") + .fails() + .stderr_contains("Permission denied"); +} diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index 2602aabde06..50dbcd3fb05 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -838,3 +838,39 @@ fn test_chown_reference_file() { .stderr_contains("ownership of 'b' retained as") .no_stdout(); } + +#[test] +#[cfg(unix)] +fn test_chown_multiple_files_error_on_first_success_on_last() { + use std::os::unix::fs::PermissionsExt; + + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + at.mkdir("a_readonly_dir"); + at.mkdir("a_readonly_dir/subdir"); + at.touch("a_readonly_dir/subdir/file"); + at.touch("b_writable_file"); + + std::fs::set_permissions( + at.plus("a_readonly_dir/subdir"), + std::fs::Permissions::from_mode(0o000), + ) + .unwrap(); + + scene + .ucmd() + .arg("-R") + .arg(&user_name) + .arg("a_readonly_dir") + .arg("b_writable_file") + .fails() + .stderr_contains("Permission denied"); +}