From 013bb285cd51ea744dfe73e1bc21f6048756106b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 18 Jan 2021 23:09:00 +0100 Subject: [PATCH] bug(chmod): chmod on symlink pointing to non existing file is failing (#1694) --- src/uu/chmod/src/chmod.rs | 19 ++++++++++++++++++- tests/by-util/test_chmod.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index eee750f90..61c56dd77 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -182,7 +182,17 @@ impl Chmoder { Ok(meta) => meta.mode() & 0o7777, Err(err) => { if !self.quiet { - show_error!("{}", err); + if is_symlink(file) { + if self.verbose { + show_info!( + "neither symbolic link '{}' nor referent has been changed", + file.display() + ); + } + return Ok(()); + } else { + show_error!("{}: '{}'", err, file.display()); + } } return Err(1); } @@ -260,3 +270,10 @@ impl Chmoder { } } } + +pub fn is_symlink>(path: P) -> bool { + match fs::symlink_metadata(path) { + Ok(m) => m.file_type().is_symlink(), + Err(_) => false, + } +} diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 1b1a50e0c..e1fff99cf 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -346,3 +346,31 @@ fn test_chmod_preserve_root() { .stderr .contains("chmod: error: it is dangerous to operate recursively on '/'")); } + +#[test] +fn test_chmod_symlink_non_existing_file() { + let (at, mut ucmd) = at_and_ucmd!(); + at.symlink_file("/non-existing", "test-long.link"); + + let result = ucmd + .arg("-R") + .arg("755") + .arg("-v") + .arg("test-long.link") + .fails(); +} + +#[test] +fn test_chmod_symlink_non_existing_recursive() { + let (at, mut ucmd) = at_and_ucmd!(); + at.mkdir("tmp"); + at.symlink_file("/non-existing", "tmp/test-long.link"); + + let result = ucmd.arg("-R").arg("755").arg("-v").arg("tmp").succeeds(); + // it should be a success + println!("stderr {}", result.stderr); + println!("stdout {}", result.stdout); + assert!(result + .stderr + .contains("neither symbolic link 'tmp/test-long.link' nor referent has been changed")); +}