mirror of
https://github.com/uutils/coreutils.git
synced 2025-07-07 21:45:01 +00:00
rm: fix too long filename corner case
This commit is contained in:
parent
931d388664
commit
9d34b622dd
2 changed files with 37 additions and 19 deletions
|
@ -429,6 +429,25 @@ fn is_writable(_path: &Path) -> bool {
|
|||
/// directory itself. In case of an error, print the error message to
|
||||
/// `stderr` and return `true`. If there were no errors, return `false`.
|
||||
fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
|
||||
// Base case 1: this is a file or a symbolic link.
|
||||
//
|
||||
// The symbolic link case is important because it could be a link to
|
||||
// a directory and we don't want to recurse. In particular, this
|
||||
// avoids an infinite recursion in the case of a link to the current
|
||||
// directory, like `ln -s . link`.
|
||||
if !path.is_dir() || path.is_symlink() {
|
||||
return remove_file(path, options);
|
||||
}
|
||||
|
||||
// Base case 2: this is a non-empty directory, but the user
|
||||
// doesn't want to descend into it.
|
||||
if options.interactive == InteractiveMode::Always
|
||||
&& !is_dir_empty(path)
|
||||
&& !prompt_descend(path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Special case: if we cannot access the metadata because the
|
||||
// filename is too long, fall back to try
|
||||
// `fs::remove_dir_all()`.
|
||||
|
@ -456,25 +475,6 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
// Base case 1: this is a file or a symbolic link.
|
||||
//
|
||||
// The symbolic link case is important because it could be a link to
|
||||
// a directory and we don't want to recurse. In particular, this
|
||||
// avoids an infinite recursion in the case of a link to the current
|
||||
// directory, like `ln -s . link`.
|
||||
if !path.is_dir() || path.is_symlink() {
|
||||
return remove_file(path, options);
|
||||
}
|
||||
|
||||
// Base case 2: this is a non-empty directory, but the user
|
||||
// doesn't want to descend into it.
|
||||
if options.interactive == InteractiveMode::Always
|
||||
&& !is_dir_empty(path)
|
||||
&& !prompt_descend(path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recursive case: this is a directory.
|
||||
let mut error = false;
|
||||
match fs::read_dir(path) {
|
||||
|
|
|
@ -218,6 +218,24 @@ fn test_recursive_multiple() {
|
|||
assert!(!at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_recursive_long_filepath() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rm_recursive_directory";
|
||||
let mkdir = "test_rm_recursive_directory/".repeat(35);
|
||||
let file_a = mkdir.clone() + "test_rm_recursive_file_a";
|
||||
assert!(file_a.len() > 1000);
|
||||
|
||||
at.mkdir_all(&mkdir);
|
||||
at.touch(&file_a);
|
||||
|
||||
ucmd.arg("-r").arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir));
|
||||
assert!(!at.file_exists(file_a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_directory_without_flag() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue