File tree Expand file tree Collapse file tree 2 files changed +64
-9
lines changed Expand file tree Collapse file tree 2 files changed +64
-9
lines changed Original file line number Diff line number Diff line change @@ -1044,7 +1044,13 @@ fn copy_dir_contents_recursive(
10441044 }
10451045 #[ cfg( not( unix) ) ]
10461046 {
1047- fs:: copy ( & from_path, & to_path) ?;
1047+ if from_path. is_symlink ( ) {
1048+ // Copy a symlink file (no-follow).
1049+ rename_symlink_fallback ( & from_path, & to_path) ?;
1050+ } else {
1051+ // Copy a regular file.
1052+ fs:: copy ( & from_path, & to_path) ?;
1053+ }
10481054 }
10491055 }
10501056
@@ -1076,14 +1082,19 @@ fn copy_file_with_hardlinks_helper(
10761082 return Ok ( ( ) ) ;
10771083 }
10781084
1079- // Regular file copy
1080- #[ cfg( all( unix, not( any( target_os = "macos" , target_os = "redox" ) ) ) ) ]
1081- {
1082- fs:: copy ( from, to) . and_then ( |_| fsxattr:: copy_xattrs ( & from, & to) ) ?;
1083- }
1084- #[ cfg( any( target_os = "macos" , target_os = "redox" ) ) ]
1085- {
1086- fs:: copy ( from, to) ?;
1085+ if from. is_symlink ( ) {
1086+ // Copy a symlink file (no-follow).
1087+ rename_symlink_fallback ( from, to) ?;
1088+ } else {
1089+ // Copy a regular file.
1090+ #[ cfg( all( unix, not( any( target_os = "macos" , target_os = "redox" ) ) ) ) ]
1091+ {
1092+ fs:: copy ( from, to) . and_then ( |_| fsxattr:: copy_xattrs ( & from, & to) ) ?;
1093+ }
1094+ #[ cfg( any( target_os = "macos" , target_os = "redox" ) ) ]
1095+ {
1096+ fs:: copy ( from, to) ?;
1097+ }
10871098 }
10881099
10891100 Ok ( ( ) )
Original file line number Diff line number Diff line change @@ -621,6 +621,50 @@ fn test_mv_symlink_into_target() {
621621 ucmd. arg ( "dir-link" ) . arg ( "dir" ) . succeeds ( ) ;
622622}
623623
624+ #[ cfg( all( unix, not( target_os = "android" ) ) ) ]
625+ #[ test]
626+ fn test_mv_broken_symlink_to_another_fs ( ) {
627+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
628+
629+ scene. fixtures . mkdir ( "foo" ) ;
630+
631+ let mount = scene
632+ . cmd ( "sudo" )
633+ . env ( "PATH" , env ! ( "PATH" ) )
634+ . args ( & [
635+ "-E" ,
636+ "--non-interactive" ,
637+ "mount" ,
638+ "none" ,
639+ "-t" ,
640+ "tmpfs" ,
641+ "foo" ,
642+ ] )
643+ . run ( ) ;
644+
645+ if !mount. succeeded ( ) {
646+ print ! ( "Test skipped; requires root user" ) ;
647+ return ;
648+ }
649+
650+ scene. fixtures . mkdir ( "bar" ) ;
651+ scene. fixtures . symlink_file ( "nonexistent" , "bar/baz" ) ;
652+
653+ scene
654+ . ucmd ( )
655+ . arg ( "bar" )
656+ . arg ( "foo" )
657+ . succeeds ( )
658+ . no_stderr ( )
659+ . no_stdout ( ) ;
660+
661+ scene
662+ . cmd ( "sudo" )
663+ . env ( "PATH" , env ! ( "PATH" ) )
664+ . args ( & [ "-E" , "--non-interactive" , "umount" , "foo" ] )
665+ . succeeds ( ) ;
666+ }
667+
624668#[ test]
625669#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
626670fn test_mv_hardlink_to_symlink ( ) {
You can’t perform that action at this time.
0 commit comments