@@ -1506,7 +1506,7 @@ fn copy_source(
15061506 if options. parents {
15071507 for ( x, y) in aligned_ancestors ( source, dest. as_path ( ) ) {
15081508 if let Ok ( src) = canonicalize ( x, MissingHandling :: Normal , ResolveMode :: Physical ) {
1509- copy_attributes ( & src, y, & options. attributes ) ?;
1509+ copy_attributes ( & src, y, options) ?;
15101510 }
15111511 }
15121512 }
@@ -1655,25 +1655,14 @@ fn copy_extended_attrs(source: &Path, dest: &Path) -> CopyResult<()> {
16551655}
16561656
16571657/// Copy the specified attributes from one path to another.
1658- pub ( crate ) fn copy_attributes (
1659- source : & Path ,
1660- dest : & Path ,
1661- attributes : & Attributes ,
1662- ) -> CopyResult < ( ) > {
1658+ pub ( crate ) fn copy_attributes ( source : & Path , dest : & Path , options : & Options ) -> CopyResult < ( ) > {
16631659 let context = & * format ! ( "{} -> {}" , source. quote( ) , dest. quote( ) ) ;
16641660 let source_metadata =
16651661 fs:: symlink_metadata ( source) . map_err ( |e| CpError :: IoErrContext ( e, context. to_owned ( ) ) ) ?;
16661662
1667- // if --no-preserve wasn't explicitly passed and we're copying a directory by default we should preserve mode
1668- let mode = if dest. is_dir ( ) && attributes. mode == ( Preserve :: No { explicit : false } ) {
1669- Preserve :: Yes { required : false }
1670- } else {
1671- attributes. mode
1672- } ;
1673-
16741663 // Ownership must be changed first to avoid interfering with mode change.
16751664 #[ cfg( unix) ]
1676- handle_preserve ( & attributes. ownership , || -> CopyResult < ( ) > {
1665+ handle_preserve ( & options . attributes . ownership , || -> CopyResult < ( ) > {
16771666 use std:: os:: unix:: prelude:: MetadataExt ;
16781667 use uucore:: perms:: Verbosity ;
16791668 use uucore:: perms:: VerbosityLevel ;
@@ -1708,14 +1697,22 @@ pub(crate) fn copy_attributes(
17081697 Ok ( ( ) )
17091698 } ) ?;
17101699
1711- handle_preserve ( & mode, || -> CopyResult < ( ) > {
1700+ handle_preserve ( & options . attributes . mode , || -> CopyResult < ( ) > {
17121701 // The `chmod()` system call that underlies the
17131702 // `fs::set_permissions()` call is unable to change the
17141703 // permissions of a symbolic link. In that case, we just
17151704 // do nothing, since every symbolic link has the same
17161705 // permissions.
17171706 if !dest. is_symlink ( ) {
1718- fs:: set_permissions ( dest, source_metadata. permissions ( ) )
1707+ // let dest_permissions = calculate_dest_permissions(
1708+ // fs::metadata(dest).ok().as_ref(),
1709+ // dest,
1710+ // &source_metadata,
1711+ // options,
1712+ // context,
1713+ // )?;
1714+ let dest_permissions = source_metadata. permissions ( ) ;
1715+ fs:: set_permissions ( dest, dest_permissions)
17191716 . map_err ( |e| CpError :: IoErrContext ( e, context. to_owned ( ) ) ) ?;
17201717 // FIXME: Implement this for windows as well
17211718 #[ cfg( feature = "feat_acl" ) ]
@@ -1727,7 +1724,7 @@ pub(crate) fn copy_attributes(
17271724 Ok ( ( ) )
17281725 } ) ?;
17291726
1730- handle_preserve ( & attributes. timestamps , || -> CopyResult < ( ) > {
1727+ handle_preserve ( & options . attributes . timestamps , || -> CopyResult < ( ) > {
17311728 let atime = FileTime :: from_last_access_time ( & source_metadata) ;
17321729 let mtime = FileTime :: from_last_modification_time ( & source_metadata) ;
17331730 if dest. is_symlink ( ) {
@@ -1740,7 +1737,7 @@ pub(crate) fn copy_attributes(
17401737 } ) ?;
17411738
17421739 #[ cfg( feature = "selinux" ) ]
1743- handle_preserve ( & attributes. context , || -> CopyResult < ( ) > {
1740+ handle_preserve ( & options . attributes . context , || -> CopyResult < ( ) > {
17441741 // Get the source context and apply it to the destination
17451742 if let Ok ( context) = selinux:: SecurityContext :: of_path ( source, false , false ) {
17461743 if let Some ( context) = context {
@@ -1758,7 +1755,7 @@ pub(crate) fn copy_attributes(
17581755 Ok ( ( ) )
17591756 } ) ?;
17601757
1761- handle_preserve ( & attributes. xattr , || -> CopyResult < ( ) > {
1758+ handle_preserve ( & options . attributes . xattr , || -> CopyResult < ( ) > {
17621759 #[ cfg( all( unix, not( target_os = "android" ) ) ) ]
17631760 {
17641761 copy_extended_attrs ( source, dest) ?;
@@ -2519,7 +2516,7 @@ fn copy_file(
25192516 if options. dereference ( source_in_command_line) {
25202517 if let Ok ( src) = canonicalize ( source, MissingHandling :: Normal , ResolveMode :: Physical ) {
25212518 if src. exists ( ) {
2522- copy_attributes ( & src, dest, & options. attributes ) ?;
2519+ copy_attributes ( & src, dest, options) ?;
25232520 }
25242521 }
25252522 } else if source_is_stream && !source. exists ( ) {
@@ -2528,7 +2525,7 @@ fn copy_file(
25282525 // attributes. However, this is already handled in the stream
25292526 // copy function (see `copy_stream` under platform/linux.rs).
25302527 } else {
2531- copy_attributes ( source, dest, & options. attributes ) ?;
2528+ copy_attributes ( source, dest, options) ?;
25322529 }
25332530
25342531 #[ cfg( feature = "selinux" ) ]
@@ -2704,7 +2701,7 @@ fn copy_link(
27042701 delete_path ( dest, options) ?;
27052702 }
27062703 symlink_file ( & link, dest, symlinked_files) ?;
2707- copy_attributes ( source, dest, & options. attributes )
2704+ copy_attributes ( source, dest, options)
27082705}
27092706
27102707/// Generate an error message if `target` is not the correct `target_type`
0 commit comments