Skip to content

Commit ab5abb9

Browse files
authored
Merge pull request #7308 from jfinkels/rm-simplify-remove-dir
rm: simplify remove_dir() helper function
2 parents c53dc91 + 464181b commit ab5abb9

File tree

2 files changed

+31
-44
lines changed

2 files changed

+31
-44
lines changed

src/uu/rm/src/rm.rs

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::os::unix::ffi::OsStrExt;
1515
use std::path::MAIN_SEPARATOR;
1616
use std::path::{Path, PathBuf};
1717
use uucore::display::Quotable;
18-
use uucore::error::{UResult, USimpleError, UUsageError};
18+
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
1919
use uucore::{
2020
format_usage, help_about, help_section, help_usage, os_str_as_bytes, prompt_yes, show_error,
2121
};
@@ -428,49 +428,35 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
428428
had_err
429429
}
430430

431+
/// Remove the given directory, asking the user for permission if necessary.
432+
///
433+
/// Returns true if it has encountered an error.
431434
fn remove_dir(path: &Path, options: &Options) -> bool {
432-
if prompt_dir(path, options) {
433-
if let Ok(mut read_dir) = fs::read_dir(path) {
434-
if options.dir || options.recursive {
435-
if read_dir.next().is_none() {
436-
match fs::remove_dir(path) {
437-
Ok(_) => {
438-
if options.verbose {
439-
println!("removed directory {}", normalize(path).quote());
440-
}
441-
}
442-
Err(e) => {
443-
if e.kind() == std::io::ErrorKind::PermissionDenied {
444-
// GNU compatibility (rm/fail-eacces.sh)
445-
show_error!(
446-
"cannot remove {}: {}",
447-
path.quote(),
448-
"Permission denied"
449-
);
450-
} else {
451-
show_error!("cannot remove {}: {}", path.quote(), e);
452-
}
453-
return true;
454-
}
455-
}
456-
} else {
457-
// directory can be read but is not empty
458-
show_error!("cannot remove {}: Directory not empty", path.quote());
459-
return true;
460-
}
461-
} else {
462-
// called to remove a symlink_dir (windows) without "-r"/"-R" or "-d"
463-
show_error!("cannot remove {}: Is a directory", path.quote());
464-
return true;
435+
// Ask the user for permission.
436+
if !prompt_dir(path, options) {
437+
return false;
438+
}
439+
440+
// Called to remove a symlink_dir (windows) without "-r"/"-R" or "-d".
441+
if !options.dir && !options.recursive {
442+
show_error!("cannot remove {}: Is a directory", path.quote());
443+
return true;
444+
}
445+
446+
// Try to remove the directory.
447+
match fs::remove_dir(path) {
448+
Ok(_) => {
449+
if options.verbose {
450+
println!("removed directory {}", normalize(path).quote());
465451
}
466-
} else {
467-
// GNU's rm shows this message if directory is empty but not readable
468-
show_error!("cannot remove {}: Directory not empty", path.quote());
469-
return true;
452+
false
453+
}
454+
Err(e) => {
455+
let e = e.map_err_context(|| format!("cannot remove {}", path.quote()));
456+
show_error!("{e}");
457+
true
470458
}
471459
}
472-
473-
false
474460
}
475461

476462
fn remove_file(path: &Path, options: &Options) -> bool {

tests/by-util/test_rm.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ fn test_rm_non_empty_directory() {
167167
at.mkdir(dir);
168168
at.touch(file_a);
169169

170-
ucmd.arg("-d")
171-
.arg(dir)
172-
.fails()
173-
.stderr_contains(format!("cannot remove '{dir}': Directory not empty"));
170+
#[cfg(windows)]
171+
let expected = "rm: cannot remove 'test_rm_non_empty_dir': The directory is not empty.\n";
172+
#[cfg(not(windows))]
173+
let expected = "rm: cannot remove 'test_rm_non_empty_dir': Directory not empty\n";
174+
ucmd.arg("-d").arg(dir).fails().stderr_only(expected);
174175
assert!(at.file_exists(file_a));
175176
assert!(at.dir_exists(dir));
176177
}

0 commit comments

Comments
 (0)