@@ -403,6 +403,50 @@ 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( windows) ]
412+ use std:: os:: windows:: fs:: symlink_file;
413+ #[ cfg( unix) ]
414+ use std:: os:: unix:: fs:: symlink;
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 ! ( std:: fs:: symlink_file( "file" , dir. path( ) . join( "symlink" ) ) ) ;
423+ check ! ( std:: fs:: hard_link( dir. path( ) . join( "symlink" ) , dir. path( ) . join( "hard_link" ) ) ) ;
424+ assert ! ( check!( std:: fs:: symlink_metadata( dir. path( ) . join( "hard_link" ) ) )
425+ . file_type( )
426+ . is_symlink( ) ) ;
427+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) ) ;
428+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
429+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) ) ;
430+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) ) ;
431+ check ! ( std:: fs:: rename( dir. path( ) . join( "file" ) , dir. path( ) . join( "file.renamed" ) ) ) ;
432+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
433+ let _ = check ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) ) ;
434+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) . is_err( ) ) ;
435+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) . is_err( ) ) ;
436+ assert ! ( std:: fs:: read_link( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
437+ assert ! ( std:: fs:: read_link( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
438+ assert_eq ! ( check!( std:: fs:: read_link( dir. path( ) . join( "symlink" ) ) ) , Path :: new( "file" ) ) ;
439+ assert_eq ! ( check!( std:: fs:: read_link( dir. path( ) . join( "hard_link" ) ) ) , Path :: new( "file" ) ) ;
440+ check ! ( std:: fs:: remove_file( dir. path( ) . join( "file.renamed" ) ) ) ;
441+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file" ) ) . is_err( ) ) ;
442+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "file.renamed" ) ) . is_err( ) ) ;
443+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "symlink" ) ) . is_err( ) ) ;
444+ assert ! ( std:: fs:: File :: open( dir. path( ) . join( "hard_link" ) ) . is_err( ) ) ;
445+ assert ! ( check!( std:: fs:: symlink_metadata( dir. path( ) . join( "hard_link" ) ) )
446+ . file_type( )
447+ . is_symlink( ) ) ;
448+ }
449+
406450/// POSIX says that whether or not `link` follows symlinks in the `old`
407451/// path is implementation-defined. We want `hard_link` to not follow
408452/// symbolic links.
0 commit comments