1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

rm: In some cases, remove_dir is doing a better job than remove_dir_all

use it when remove_dir_all failed

GNU compatibility (rm/empty-inacc.sh)
This commit is contained in:
Sylvestre Ledru 2023-10-14 11:41:48 +02:00
parent 21c8538e0b
commit 505ef714b9
2 changed files with 29 additions and 8 deletions

View file

@ -330,14 +330,20 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
if options.recursive && (!is_root || !options.preserve_root) { if options.recursive && (!is_root || !options.preserve_root) {
if options.interactive != InteractiveMode::Always && !options.verbose { if options.interactive != InteractiveMode::Always && !options.verbose {
if let Err(e) = fs::remove_dir_all(path) { if let Err(e) = fs::remove_dir_all(path) {
had_err = true; // GNU compatibility (rm/empty-inacc.sh)
if e.kind() == std::io::ErrorKind::PermissionDenied { // remove_dir_all failed. maybe it is because of the permissions
// GNU compatibility (rm/fail-eacces.sh) // but if the directory is empty, remove_dir might work.
// here, GNU doesn't use some kind of remove_dir_all // So, let's try that before failing for real
// It will show directory+file if let Err(_e) = fs::remove_dir(path) {
show_error!("cannot remove {}: {}", path.quote(), "Permission denied"); had_err = true;
} else { if e.kind() == std::io::ErrorKind::PermissionDenied {
show_error!("cannot remove {}: {}", path.quote(), e); // GNU compatibility (rm/fail-eacces.sh)
// here, GNU doesn't use some kind of remove_dir_all
// It will show directory+file
show_error!("cannot remove {}: {}", path.quote(), "Permission denied");
} else {
show_error!("cannot remove {}: {}", path.quote(), e);
}
} }
} }
} else { } else {

View file

@ -647,6 +647,21 @@ fn test_prompt_write_protected_no() {
assert!(at.file_exists(file_2)); assert!(at.file_exists(file_2));
} }
#[cfg(feature = "chmod")]
#[test]
fn test_remove_inaccessible_dir() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let dir_1 = "test_rm_protected";
at.mkdir(dir_1);
scene.ccmd("chmod").arg("0").arg(dir_1).succeeds();
scene.ucmd().arg("-rf").arg(dir_1).succeeds();
assert!(!at.dir_exists(dir_1));
}
#[test] #[test]
#[cfg(not(windows))] #[cfg(not(windows))]
fn test_fifo_removal() { fn test_fifo_removal() {