@@ -31,6 +31,16 @@ use crate::{
3131 copy_file,
3232} ;
3333
34+ /// Represents a directory that needs permission fixup after copying its contents.
35+ struct DirNeedingPermissions {
36+ /// Absolute path to the source directory
37+ source : PathBuf ,
38+ /// Path to the destination directory
39+ dest : PathBuf ,
40+ /// Whether this directory was freshly created by the copy operation
41+ was_created : bool ,
42+ }
43+
3444/// Ensure a Windows path starts with a `\\?`.
3545#[ cfg( target_os = "windows" ) ]
3646fn adjust_canonicalization ( p : & Path ) -> Cow < ' _ , Path > {
@@ -237,7 +247,12 @@ impl Entry {
237247
238248#[ allow( clippy:: too_many_arguments) ]
239249/// Copy a single entry during a directory traversal.
240- /// Returns a bool value indicating whether this function created a directory or not
250+ ///
251+ /// # Returns
252+ ///
253+ /// Returns `Ok(true)` if this function created a new directory, `Ok(false)` otherwise.
254+ /// This information is used to determine whether default directory permissions should
255+ /// be preserved during attribute copying.
241256fn copy_direntry (
242257 progress_bar : Option < & ProgressBar > ,
243258 entry : & Entry ,
@@ -422,7 +437,7 @@ pub(crate) fn copy_directory(
422437 let mut last_iter: Option < DirEntry > = None ;
423438
424439 // Keep track of all directories we've created that need permission fixes
425- let mut dirs_needing_permissions: Vec < ( PathBuf , PathBuf , bool ) > = Vec :: new ( ) ;
440+ let mut dirs_needing_permissions: Vec < DirNeedingPermissions > = Vec :: new ( ) ;
426441
427442 // Traverse the contents of the directory, copying each one.
428443 for direntry_result in WalkDir :: new ( root)
@@ -481,11 +496,11 @@ pub(crate) fn copy_directory(
481496 continue ;
482497 }
483498 // Add this directory to our list for permission fixing later
484- dirs_needing_permissions. push ( (
485- entry. source_absolute . clone ( ) ,
486- entry. local_to_target . clone ( ) ,
487- created,
488- ) ) ;
499+ dirs_needing_permissions. push ( DirNeedingPermissions {
500+ source : entry. source_absolute . clone ( ) ,
501+ dest : entry. local_to_target . clone ( ) ,
502+ was_created : created,
503+ } ) ;
489504
490505 // If true, last_iter is not a parent of this iter.
491506 // The means we just exited a directory.
@@ -534,8 +549,8 @@ pub(crate) fn copy_directory(
534549
535550 // Fix permissions for all directories we created
536551 // This ensures that even sibling directories get their permissions fixed
537- for ( source_path , dest_path , created ) in dirs_needing_permissions {
538- copy_attributes ( & source_path , & dest_path , & options. attributes , created ) ?;
552+ for dir in dirs_needing_permissions {
553+ copy_attributes ( & dir . source , & dir . dest , & options. attributes , dir . was_created ) ?;
539554 }
540555
541556 // Also fix permissions for parent directories,
0 commit comments