File tree Expand file tree Collapse file tree 2 files changed +63
-9
lines changed
Expand file tree Collapse file tree 2 files changed +63
-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 @@ -16,6 +16,8 @@ use uutests::new_ucmd;
1616use uutests:: util:: TestScenario ;
1717use uutests:: { at_and_ucmd, util_name} ;
1818
19+ pub const PATH : & str = env ! ( "PATH" ) ;
20+
1921#[ test]
2022fn test_mv_invalid_arg ( ) {
2123 new_ucmd ! ( ) . arg ( "--definitely-invalid" ) . fails_with_code ( 1 ) ;
@@ -621,6 +623,49 @@ fn test_mv_symlink_into_target() {
621623 ucmd. arg ( "dir-link" ) . arg ( "dir" ) . succeeds ( ) ;
622624}
623625
626+ #[ cfg( all( unix, not( target_os = "android" ) ) ) ]
627+ #[ test]
628+ fn test_mv_broken_symlink_to_another_fs ( ) {
629+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
630+
631+ scene. fixtures . mkdir ( "foo" ) ;
632+
633+ let mount = scene
634+ . cmd ( "sudo" )
635+ . env ( "PATH" , PATH )
636+ . args ( & [
637+ "-E" ,
638+ "--non-interactive" ,
639+ "mount" ,
640+ "none" ,
641+ "-t" ,
642+ "tmpfs" ,
643+ "foo" ,
644+ ] )
645+ . run ( ) ;
646+
647+ if !mount. succeeded ( ) {
648+ print ! ( "Test skipped; requires root user" ) ;
649+ return ;
650+ }
651+
652+ scene. fixtures . mkdir ( "bar" ) ;
653+ scene. fixtures . symlink_file ( "nonexistent" , "bar/baz" ) ;
654+
655+ scene
656+ . ucmd ( )
657+ . arg ( "bar" )
658+ . arg ( "foo" )
659+ . succeeds ( )
660+ . no_stderr ( )
661+ . no_stdout ( ) ;
662+
663+ scene
664+ . cmd ( "sudo" )
665+ . args ( & [ "-E" , "--non-interactive" , "umount" , "foo" ] )
666+ . succeeds ( ) ;
667+ }
668+
624669#[ test]
625670#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
626671fn test_mv_hardlink_to_symlink ( ) {
You can’t perform that action at this time.
0 commit comments