File tree Expand file tree Collapse file tree 2 files changed +19
-3
lines changed
Expand file tree Collapse file tree 2 files changed +19
-3
lines changed Original file line number Diff line number Diff 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 {
Original file line number Diff line number Diff 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) ]
412422fn test_chmod_recursive ( ) {
You can’t perform that action at this time.
0 commit comments