1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #7308 from jfinkels/rm-simplify-remove-dir

rm: simplify remove_dir() helper function
This commit is contained in:
Sylvestre Ledru 2025-02-17 00:13:37 +01:00 committed by GitHub
commit ab5abb9f13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 45 deletions

View file

@ -15,7 +15,7 @@ use std::os::unix::ffi::OsStrExt;
use std::path::MAIN_SEPARATOR; use std::path::MAIN_SEPARATOR;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::{ use uucore::{
format_usage, help_about, help_section, help_usage, os_str_as_bytes, prompt_yes, show_error, format_usage, help_about, help_section, help_usage, os_str_as_bytes, prompt_yes, show_error,
}; };
@ -428,49 +428,35 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
had_err had_err
} }
/// Remove the given directory, asking the user for permission if necessary.
///
/// Returns true if it has encountered an error.
fn remove_dir(path: &Path, options: &Options) -> bool { fn remove_dir(path: &Path, options: &Options) -> bool {
if prompt_dir(path, options) { // Ask the user for permission.
if let Ok(mut read_dir) = fs::read_dir(path) { if !prompt_dir(path, options) {
if options.dir || options.recursive { return false;
if read_dir.next().is_none() {
match fs::remove_dir(path) {
Ok(_) => {
if options.verbose {
println!("removed directory {}", normalize(path).quote());
}
}
Err(e) => {
if e.kind() == std::io::ErrorKind::PermissionDenied {
// GNU compatibility (rm/fail-eacces.sh)
show_error!(
"cannot remove {}: {}",
path.quote(),
"Permission denied"
);
} else {
show_error!("cannot remove {}: {}", path.quote(), e);
}
return true;
}
}
} else {
// directory can be read but is not empty
show_error!("cannot remove {}: Directory not empty", path.quote());
return true;
}
} else {
// called to remove a symlink_dir (windows) without "-r"/"-R" or "-d"
show_error!("cannot remove {}: Is a directory", path.quote());
return true;
}
} else {
// GNU's rm shows this message if directory is empty but not readable
show_error!("cannot remove {}: Directory not empty", path.quote());
return true;
}
} }
false // Called to remove a symlink_dir (windows) without "-r"/"-R" or "-d".
if !options.dir && !options.recursive {
show_error!("cannot remove {}: Is a directory", path.quote());
return true;
}
// Try to remove the directory.
match fs::remove_dir(path) {
Ok(_) => {
if options.verbose {
println!("removed directory {}", normalize(path).quote());
}
false
}
Err(e) => {
let e = e.map_err_context(|| format!("cannot remove {}", path.quote()));
show_error!("{e}");
true
}
}
} }
fn remove_file(path: &Path, options: &Options) -> bool { fn remove_file(path: &Path, options: &Options) -> bool {

View file

@ -167,10 +167,11 @@ fn test_rm_non_empty_directory() {
at.mkdir(dir); at.mkdir(dir);
at.touch(file_a); at.touch(file_a);
ucmd.arg("-d") #[cfg(windows)]
.arg(dir) let expected = "rm: cannot remove 'test_rm_non_empty_dir': The directory is not empty.\n";
.fails() #[cfg(not(windows))]
.stderr_contains(format!("cannot remove '{dir}': Directory not empty")); let expected = "rm: cannot remove 'test_rm_non_empty_dir': Directory not empty\n";
ucmd.arg("-d").arg(dir).fails().stderr_only(expected);
assert!(at.file_exists(file_a)); assert!(at.file_exists(file_a));
assert!(at.dir_exists(dir)); assert!(at.dir_exists(dir));
} }