Skip to content

Commit d28cb30

Browse files
authored
Merge pull request #9990 from cerdelen/chmod_recursive_hyper_nested_dirs
Chmod recursive hyper nested dirs
1 parent baebd29 commit d28cb30

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/uu/chmod/src/chmod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,14 +432,20 @@ impl Chmoder {
432432

433433
// If the path is a directory (or we should follow symlinks), recurse into it
434434
if (!file_path.is_symlink() || should_follow_symlink) && file_path.is_dir() {
435+
// We buffer all paths in this dir to not keep to be able to close the fd so not
436+
// too many fd's are open during the recursion
437+
let mut paths_in_this_dir = Vec::new();
438+
435439
for dir_entry in file_path.read_dir()? {
436-
let path = match dir_entry {
437-
Ok(entry) => entry.path(),
440+
match dir_entry {
441+
Ok(entry) => paths_in_this_dir.push(entry.path()),
438442
Err(err) => {
439443
r = r.and(Err(err.into()));
440444
continue;
441445
}
442-
};
446+
}
447+
}
448+
for path in paths_in_this_dir {
443449
if path.is_symlink() {
444450
r = self.handle_symlink_during_recursion(&path).and(r);
445451
} else {

tests/by-util/test_chmod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,16 @@ fn test_chmod_recursive_correct_exit_code() {
407407
.stderr_is(err_msg);
408408
}
409409

410+
#[test]
411+
fn test_chmod_hyper_recursive_directory_tree_does_not_fail() {
412+
let (at, mut ucmd) = at_and_ucmd!();
413+
let mkdir = "a/".repeat(400);
414+
415+
at.mkdir_all(&mkdir);
416+
417+
ucmd.arg("-R").arg("777").arg("a").succeeds();
418+
}
419+
410420
#[test]
411421
#[allow(clippy::unreadable_literal)]
412422
fn test_chmod_recursive() {

0 commit comments

Comments
 (0)