File tree Expand file tree Collapse file tree 2 files changed +61
-9
lines changed Expand file tree Collapse file tree 2 files changed +61
-9
lines changed Original file line number Diff line number Diff line change @@ -1044,7 +1044,11 @@ 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+ rename_symlink_fallback ( & from_path, & to_path) ?;
1049+ } else {
1050+ fs:: copy ( & from_path, & to_path) ?;
1051+ }
10481052 }
10491053 }
10501054
@@ -1076,14 +1080,19 @@ fn copy_file_with_hardlinks_helper(
10761080 return Ok ( ( ) ) ;
10771081 }
10781082
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) ?;
1083+ if from. is_symlink ( ) {
1084+ // Symlink copy
1085+ rename_symlink_fallback ( from, to) ?;
1086+ } else {
1087+ // Regular file copy
1088+ #[ cfg( all( unix, not( any( target_os = "macos" , target_os = "redox" ) ) ) ) ]
1089+ {
1090+ fs:: copy ( from, to) . and_then ( |_| fsxattr:: copy_xattrs ( & from, & to) ) ?;
1091+ }
1092+ #[ cfg( any( target_os = "macos" , target_os = "redox" ) ) ]
1093+ {
1094+ fs:: copy ( from, to) ?;
1095+ }
10871096 }
10881097
10891098 Ok ( ( ) )
Original file line number Diff line number Diff line change @@ -621,6 +621,49 @@ 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+ #[ ignore = "requires sudo" ]
626+ #[ test]
627+ fn test_mv_broken_symlink_to_another_fs ( ) {
628+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
629+
630+ scene. fixtures . mkdir ( "foo" ) ;
631+
632+ let mount = scene
633+ . cmd ( "sudo" )
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+ . args ( & [ "-E" , "--non-interactive" , "umount" , "foo" ] )
664+ . succeeds ( ) ;
665+ }
666+
624667#[ test]
625668#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
626669fn test_mv_hardlink_to_symlink ( ) {
You can’t perform that action at this time.
0 commit comments