mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 06:42:42 +00:00
chmod: change permissions for files present even when there is a missing file
This commit is contained in:
parent
d3fc0e8706
commit
946c8d2d4a
2 changed files with 77 additions and 6 deletions
|
@ -12,12 +12,12 @@ use std::fs;
|
|||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{ExitCode, UResult, USimpleError, UUsageError};
|
||||
use uucore::error::{set_exit_code, ExitCode, UResult, USimpleError, UUsageError};
|
||||
use uucore::fs::display_permissions_unix;
|
||||
use uucore::libc::mode_t;
|
||||
#[cfg(not(windows))]
|
||||
use uucore::mode;
|
||||
use uucore::{format_usage, show_error};
|
||||
use uucore::{format_usage, show, show_error};
|
||||
|
||||
const ABOUT: &str = "Change the mode of each FILE to MODE.\n\
|
||||
With --reference, change the mode of each FILE to that of RFILE.";
|
||||
|
@ -195,21 +195,24 @@ impl Chmoder {
|
|||
filename.quote()
|
||||
);
|
||||
if !self.quiet {
|
||||
return Err(USimpleError::new(
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!("cannot operate on dangling symlink {}", filename.quote()),
|
||||
));
|
||||
}
|
||||
} else if !self.quiet {
|
||||
return Err(USimpleError::new(
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot access {}: No such file or directory",
|
||||
filename.quote()
|
||||
),
|
||||
)
|
||||
));
|
||||
}
|
||||
return Err(ExitCode::new(1));
|
||||
// GNU exits with exit code 1 even if -q or --quiet are passed
|
||||
// So we set the exit code, because it hasn't been set yet if `self.quiet` is true.
|
||||
set_exit_code(1);
|
||||
continue;
|
||||
}
|
||||
if self.recursive && self.preserve_root && filename == "/" {
|
||||
return Err(USimpleError::new(
|
||||
|
|
|
@ -574,3 +574,71 @@ fn test_mode_after_dash_dash() {
|
|||
ucmd,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_file_after_non_existing_file() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
at.touch(TEST_FILE);
|
||||
at.touch("file2");
|
||||
set_permissions(at.plus(TEST_FILE), Permissions::from_mode(0o664)).unwrap();
|
||||
set_permissions(at.plus("file2"), Permissions::from_mode(0o664)).unwrap();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("u+x")
|
||||
.arg("does-not-exist")
|
||||
.arg(TEST_FILE)
|
||||
.fails()
|
||||
.stderr_contains("chmod: cannot access 'does-not-exist': No such file or directory")
|
||||
.code_is(1);
|
||||
|
||||
assert_eq!(at.metadata(TEST_FILE).permissions().mode(), 0o100764);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("u+x")
|
||||
.arg("--q")
|
||||
.arg("does-not-exist")
|
||||
.arg("file2")
|
||||
.fails()
|
||||
.no_stderr()
|
||||
.code_is(1);
|
||||
assert_eq!(at.metadata("file2").permissions().mode(), 0o100764);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_file_symlink_after_non_existing_file() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let existing = "file";
|
||||
let test_existing_symlink = "file_symlink";
|
||||
|
||||
let non_existing = "test_chmod_symlink_non_existing_file";
|
||||
let test_dangling_symlink = "test_chmod_symlink_non_existing_file_symlink";
|
||||
let expected_stdout = &format!(
|
||||
"failed to change mode of '{test_dangling_symlink}' from 0000 (---------) to 0000 (---------)"
|
||||
);
|
||||
let expected_stderr = &format!("cannot operate on dangling symlink '{test_dangling_symlink}'");
|
||||
|
||||
at.touch(existing);
|
||||
set_permissions(at.plus(existing), Permissions::from_mode(0o664)).unwrap();
|
||||
at.symlink_file(non_existing, test_dangling_symlink);
|
||||
at.symlink_file(existing, test_existing_symlink);
|
||||
|
||||
// this cannot succeed since the symbolic link dangles
|
||||
// but the metadata for the existing target should change
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("u+x")
|
||||
.arg("-v")
|
||||
.arg(test_dangling_symlink)
|
||||
.arg(test_existing_symlink)
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stdout_contains(expected_stdout)
|
||||
.stderr_contains(expected_stderr);
|
||||
assert_eq!(
|
||||
at.metadata(test_existing_symlink).permissions().mode(),
|
||||
0o100764
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue