@@ -2851,3 +2851,54 @@ fn test_mv_xattr_enotsup_silent() {
28512851 std:: fs:: remove_file ( "/dev/shm/mv_test" ) . ok ( ) ;
28522852 }
28532853}
2854+
2855+ /// Test that symlinks inside directories are preserved during cross-device moves
2856+ /// (not expanded into full copies of their targets)
2857+ #[ test]
2858+ #[ cfg( target_os = "linux" ) ]
2859+ fn test_mv_cross_device_symlink_preserved ( ) {
2860+ use std:: fs;
2861+ use std:: os:: unix:: fs:: symlink;
2862+ use tempfile:: TempDir ;
2863+
2864+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
2865+ let at = & scene. fixtures ;
2866+
2867+ // Create a directory with a symlink to /etc inside
2868+ at. mkdir ( "src_dir" ) ;
2869+ at. write ( "src_dir/local.txt" , "local content" ) ;
2870+ symlink ( "/etc" , at. plus ( "src_dir/etc_link" ) ) . expect ( "Failed to create symlink" ) ;
2871+
2872+ // Verify initial state
2873+ assert ! ( at. is_symlink( "src_dir/etc_link" ) ) ;
2874+
2875+ // Force cross-filesystem move using /dev/shm (tmpfs)
2876+ let target_dir =
2877+ TempDir :: new_in ( "/dev/shm/" ) . expect ( "Unable to create temp directory in /dev/shm" ) ;
2878+ let target_path = target_dir. path ( ) . join ( "dst_dir" ) ;
2879+
2880+ scene
2881+ . ucmd ( )
2882+ . arg ( "src_dir" )
2883+ . arg ( target_path. to_str ( ) . unwrap ( ) )
2884+ . succeeds ( )
2885+ . no_stderr ( ) ;
2886+
2887+ // Verify source was removed
2888+ assert ! ( !at. dir_exists( "src_dir" ) ) ;
2889+
2890+ // Verify the symlink was preserved (not expanded)
2891+ let moved_symlink = target_path. join ( "etc_link" ) ;
2892+ assert ! (
2893+ moved_symlink. is_symlink( ) ,
2894+ "etc_link should still be a symlink after cross-device move"
2895+ ) ;
2896+ assert_eq ! (
2897+ fs:: read_link( & moved_symlink) . expect( "Failed to read symlink" ) ,
2898+ std:: path:: Path :: new( "/etc" ) ,
2899+ "symlink should still point to /etc"
2900+ ) ;
2901+
2902+ // Verify the regular file was also moved
2903+ assert ! ( target_path. join( "local.txt" ) . exists( ) ) ;
2904+ }
0 commit comments