@@ -403,6 +403,66 @@ fn dir_searchable_unreadable() {
403403 . is_err( ) ) ;
404404}
405405
406+ /// This test is the same as `symlink_hard_link` but uses `std::fs`'
407+ /// ambient API instead of `cap_std`. The purpose of this test is to
408+ /// confirm fundamentally OS-specific behaviors.
409+ #[ test]
410+ fn symlink_hard_link_ambient ( ) {
411+ #[ cfg( unix) ]
412+ use std:: os:: unix:: fs:: symlink;
413+ #[ cfg( windows) ]
414+ use std:: os:: windows:: fs:: symlink_file;
415+
416+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
417+
418+ check ! ( std:: fs:: File :: create( dir. path( ) . join( "file" ) ) ) ;
419+ #[ cfg( not( windows) ) ]
420+ check ! ( symlink( "file" , dir. path( ) . join( "symlink" ) ) ) ;
421+ #[ cfg( windows) ]
422+ check ! ( symlink_file( "file" , dir. path( ) . join( "symlink" ) ) ) ;
423+ check ! ( std:: fs:: hard_link(
424+ dir. path( ) . join( "symlink" ) ,
425+ dir. path( ) . join( "hard_link" )
426+ ) ) ;
427+ assert ! (
428+ check!( std:: fs:: symlink_metadata( dir. path( ) . join( "hard_link" ) ) )
429+ . file_type( )
430+ . is_symlink( )
431+ ) ;
432+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) ) ;
433+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
434+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) ) ;
435+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) ) ;
436+ check ! ( std:: fs:: rename(
437+ dir. path( ) . join( "file" ) ,
438+ dir. path( ) . join( "file.renamed" )
439+ ) ) ;
440+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
441+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) ) ;
442+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) . is_err( ) ) ;
443+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) . is_err( ) ) ;
444+ assert ! ( std:: fs:: read_link( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
445+ assert ! ( std:: fs:: read_link( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
446+ assert_eq ! (
447+ check!( std:: fs:: read_link( dir. path( ) . join( "symlink" ) ) ) ,
448+ Path :: new( "file" )
449+ ) ;
450+ assert_eq ! (
451+ check!( std:: fs:: read_link( dir. path( ) . join( "hard_link" ) ) ) ,
452+ Path :: new( "file" )
453+ ) ;
454+ check ! ( std:: fs:: remove_file( dir. path( ) . join( "file.renamed" ) ) ) ;
455+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
456+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
457+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) . is_err( ) ) ;
458+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) . is_err( ) ) ;
459+ assert ! (
460+ check!( std:: fs:: symlink_metadata( dir. path( ) . join( "hard_link" ) ) )
461+ . file_type( )
462+ . is_symlink( )
463+ ) ;
464+ }
465+
406466/// POSIX says that whether or not `link` follows symlinks in the `old`
407467/// path is implementation-defined. We want `hard_link` to not follow
408468/// symbolic links.
0 commit comments