mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Merge pull request #5403 from sylvestre/rm
rm: In some cases, remove_dir is doing a better job than remove_dir_all
This commit is contained in:
commit
541ac6a813
2 changed files with 30 additions and 9 deletions
|
@ -3,7 +3,7 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (path) eacces
|
// spell-checker:ignore (path) eacces inacc
|
||||||
|
|
||||||
use clap::{builder::ValueParser, crate_version, parser::ValueSource, Arg, ArgAction, Command};
|
use clap::{builder::ValueParser, crate_version, parser::ValueSource, Arg, ArgAction, Command};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -330,6 +330,11 @@ 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) {
|
||||||
|
// GNU compatibility (rm/empty-inacc.sh)
|
||||||
|
// remove_dir_all failed. maybe it is because of the permissions
|
||||||
|
// but if the directory is empty, remove_dir might work.
|
||||||
|
// So, let's try that before failing for real
|
||||||
|
if let Err(_e) = fs::remove_dir(path) {
|
||||||
had_err = true;
|
had_err = true;
|
||||||
if e.kind() == std::io::ErrorKind::PermissionDenied {
|
if e.kind() == std::io::ErrorKind::PermissionDenied {
|
||||||
// GNU compatibility (rm/fail-eacces.sh)
|
// GNU compatibility (rm/fail-eacces.sh)
|
||||||
|
@ -340,6 +345,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
||||||
show_error!("cannot remove {}: {}", path.quote(), e);
|
show_error!("cannot remove {}: {}", path.quote(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut dirs: VecDeque<DirEntry> = VecDeque::new();
|
let mut dirs: VecDeque<DirEntry> = VecDeque::new();
|
||||||
// The Paths to not descend into. We need to this because WalkDir doesn't have a way, afaik, to not descend into a directory
|
// The Paths to not descend into. We need to this because WalkDir doesn't have a way, afaik, to not descend into a directory
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue