@@ -267,6 +267,7 @@ fn copy_direntry(
267267 copied_destinations : & HashSet < PathBuf > ,
268268 copied_files : & mut HashMap < FileInformation , PathBuf > ,
269269 created_parent_dirs : & mut HashSet < PathBuf > ,
270+ #[ cfg( unix) ] orig_umask : u32 ,
270271) -> CopyResult < bool > {
271272 let source_is_symlink = entry_is_symlink;
272273 let source_is_dir = if source_is_symlink && !options. dereference {
@@ -283,12 +284,7 @@ fn copy_direntry(
283284 return if entry. target_is_file {
284285 Err ( translate ! ( "cp-error-cannot-overwrite-non-directory-with-directory" ) . into ( ) )
285286 } else {
286- build_dir (
287- & entry. local_to_target ,
288- false ,
289- options,
290- Some ( & entry. source_absolute ) ,
291- ) ?;
287+ build_dir ( & entry. local_to_target , false ) ?;
292288 if options. verbose {
293289 println ! (
294290 "{}" ,
@@ -311,6 +307,8 @@ fn copy_direntry(
311307 copied_files,
312308 created_parent_dirs,
313309 false ,
310+ #[ cfg( unix) ]
311+ orig_umask,
314312 )
315313 {
316314 if preserve_hard_links {
@@ -364,6 +362,7 @@ pub(crate) fn copy_directory(
364362 copied_files : & mut HashMap < FileInformation , PathBuf > ,
365363 created_parent_dirs : & mut HashSet < PathBuf > ,
366364 source_in_command_line : bool ,
365+ #[ cfg( unix) ] orig_umask : u32 ,
367366) -> CopyResult < ( ) > {
368367 // if no-dereference is enabled and this is a symlink, copy it as a file
369368 if !options. dereference ( source_in_command_line) && root. is_symlink ( ) {
@@ -377,6 +376,8 @@ pub(crate) fn copy_directory(
377376 copied_files,
378377 created_parent_dirs,
379378 source_in_command_line,
379+ #[ cfg( unix) ]
380+ orig_umask,
380381 ) ;
381382 }
382383
@@ -402,7 +403,7 @@ pub(crate) fn copy_directory(
402403 let tmp = if options. parents {
403404 if let Some ( parent) = root. parent ( ) {
404405 let new_target = target. join ( parent) ;
405- build_dir ( & new_target, true , options , None ) ?;
406+ build_dir ( & new_target, true ) ?;
406407 if options. verbose {
407408 // For example, if copying file `a/b/c` and its parents
408409 // to directory `d/`, then print
@@ -472,6 +473,8 @@ pub(crate) fn copy_directory(
472473 copied_destinations,
473474 copied_files,
474475 created_parent_dirs,
476+ #[ cfg( unix) ]
477+ orig_umask,
475478 ) ?;
476479
477480 // We omit certain permissions when creating directories
@@ -496,6 +499,8 @@ pub(crate) fn copy_directory(
496499 & options. attributes ,
497500 false ,
498501 options. set_selinux_context ,
502+ #[ cfg( unix) ]
503+ orig_umask,
499504 ) ?;
500505 continue ;
501506 }
@@ -539,6 +544,8 @@ pub(crate) fn copy_directory(
539544 & options. attributes ,
540545 false ,
541546 options. set_selinux_context ,
547+ #[ cfg( unix) ]
548+ orig_umask,
542549 ) ?;
543550 }
544551 }
@@ -561,6 +568,8 @@ pub(crate) fn copy_directory(
561568 & options. attributes ,
562569 dir. was_created ,
563570 options. set_selinux_context ,
571+ #[ cfg( unix) ]
572+ orig_umask,
564573 ) ?;
565574
566575 #[ cfg( all( feature = "selinux" , target_os = "linux" ) ) ]
@@ -581,6 +590,8 @@ pub(crate) fn copy_directory(
581590 & options. attributes ,
582591 false ,
583592 options. set_selinux_context ,
593+ #[ cfg( unix) ]
594+ orig_umask,
584595 ) ?;
585596
586597 #[ cfg( all( feature = "selinux" , target_os = "linux" ) ) ]
@@ -620,59 +631,12 @@ pub fn path_has_prefix(p1: &Path, p2: &Path) -> io::Result<bool> {
620631
621632/// Builds a directory at the specified path with the given options.
622633///
623- /// # Notes
624- /// - If `copy_attributes_from` is `Some`, the new directory's attributes will be
625- /// copied from the provided file. Otherwise, the new directory will have the default
626- /// attributes for the current user.
627- /// - This method excludes certain permissions if ownership or special mode bits could
628- /// potentially change. (See `test_dir_perm_race_with_preserve_mode_and_ownership`)
629- /// - The `recursive` flag determines whether parent directories should be created
630- /// if they do not already exist.
631- // we need to allow unused_variable since `options` might be unused in non unix systems
632- #[ allow( unused_variables) ]
633- fn build_dir (
634- path : & PathBuf ,
635- recursive : bool ,
636- options : & Options ,
637- copy_attributes_from : Option < & Path > ,
638- ) -> CopyResult < ( ) > {
634+ /// The `recursive` flag determines whether parent directories should be created if they do not
635+ /// already exist.
636+ #[ inline]
637+ fn build_dir ( path : & PathBuf , recursive : bool ) -> CopyResult < ( ) > {
639638 let mut builder = fs:: DirBuilder :: new ( ) ;
640639 builder. recursive ( recursive) ;
641-
642- // To prevent unauthorized access before the folder is ready,
643- // exclude certain permissions if ownership or special mode bits
644- // could potentially change.
645- #[ cfg( unix) ]
646- {
647- use crate :: Preserve ;
648- use std:: os:: unix:: fs:: PermissionsExt ;
649-
650- // we need to allow trivial casts here because some systems like linux have u32 constants in
651- // in libc while others don't.
652- #[ allow( clippy:: unnecessary_cast) ]
653- let mut excluded_perms = if matches ! ( options. attributes. ownership, Preserve :: Yes { .. } ) {
654- libc:: S_IRWXG | libc:: S_IRWXO // exclude rwx for group and other
655- } else if matches ! ( options. attributes. mode, Preserve :: Yes { .. } ) {
656- libc:: S_IWGRP | libc:: S_IWOTH //exclude w for group and other
657- } else {
658- 0
659- } as u32 ;
660-
661- let umask = if let ( Some ( from) , Preserve :: Yes { .. } ) =
662- ( copy_attributes_from, options. attributes . mode )
663- {
664- !fs:: symlink_metadata ( from) ?. permissions ( ) . mode ( )
665- } else {
666- uucore:: mode:: get_umask ( )
667- } ;
668-
669- excluded_perms |= umask;
670- // Always keep the owner write bit so we can copy files into the directory.
671- // The correct final permissions are applied afterward by dirs_needing_permissions.
672- let mode = ( !excluded_perms & 0o777 ) | 0o200 ; // mask to permission bits, always keep owner write
673- std:: os:: unix:: fs:: DirBuilderExt :: mode ( & mut builder, mode) ;
674- }
675-
676640 builder. create ( path) ?;
677641 Ok ( ( ) )
678642}
0 commit comments