@@ -7,6 +7,8 @@ use nix::unistd::ForkResult::*;
77use nix:: sys:: signal:: { SaFlags , SigAction , SigHandler , SigSet , Signal , sigaction} ;
88use nix:: sys:: wait:: * ;
99use nix:: sys:: stat:: { self , Mode , SFlag } ;
10+ #[ cfg( not( target_os = "redox" ) ) ]
11+ use nix:: pty:: { posix_openpt, grantpt, unlockpt, ptsname} ;
1012use nix:: errno:: Errno ;
1113#[ cfg( not( target_os = "redox" ) ) ]
1214use nix:: Error ;
@@ -19,6 +21,8 @@ use std::fs::{self, File};
1921use std:: io:: Write ;
2022use std:: mem;
2123use std:: os:: unix:: prelude:: * ;
24+ #[ cfg( not( target_os = "redox" ) ) ]
25+ use std:: path:: Path ;
2226use tempfile:: { tempdir, tempfile} ;
2327use libc:: { _exit, off_t} ;
2428
@@ -964,3 +968,46 @@ fn test_setfsuid() {
964968 // open the temporary file with the current thread filesystem UID
965969 fs:: File :: open ( temp_path_2) . unwrap ( ) ;
966970}
971+
972+ #[ test]
973+ #[ cfg( not( target_os = "redox" ) ) ]
974+ fn test_ttyname ( ) {
975+ let fd = posix_openpt ( OFlag :: O_RDWR ) . expect ( "posix_openpt failed" ) ;
976+ assert ! ( fd. as_raw_fd( ) > 0 ) ;
977+
978+ // on linux, we can just call ttyname on the pty master directly, but
979+ // apparently osx requires that ttyname is called on a slave pty (can't
980+ // find this documented anywhere, but it seems to empirically be the case)
981+ grantpt ( & fd) . expect ( "grantpt failed" ) ;
982+ unlockpt ( & fd) . expect ( "unlockpt failed" ) ;
983+ let sname = unsafe { ptsname ( & fd) } . expect ( "ptsname failed" ) ;
984+ let fds = open (
985+ Path :: new ( & sname) ,
986+ OFlag :: O_RDWR ,
987+ stat:: Mode :: empty ( ) ,
988+ ) . expect ( "open failed" ) ;
989+ assert ! ( fds > 0 ) ;
990+
991+ let name = ttyname ( fds) . expect ( "ttyname failed" ) ;
992+ assert ! ( name. starts_with( "/dev" ) ) ;
993+ }
994+
995+ #[ test]
996+ #[ cfg( not( target_os = "redox" ) ) ]
997+ fn test_ttyname_not_pty ( ) {
998+ let fd = File :: open ( "/dev/zero" ) . unwrap ( ) ;
999+ assert ! ( fd. as_raw_fd( ) > 0 ) ;
1000+ assert_eq ! ( ttyname( fd. as_raw_fd( ) ) , Err ( Error :: Sys ( Errno :: ENOTTY ) ) ) ;
1001+ }
1002+
1003+ #[ test]
1004+ #[ cfg( all( not( target_os = "redox" ) , not( target_env = "musl" ) ) ) ]
1005+ fn test_ttyname_invalid_fd ( ) {
1006+ assert_eq ! ( ttyname( -1 ) , Err ( Error :: Sys ( Errno :: EBADF ) ) ) ;
1007+ }
1008+
1009+ #[ test]
1010+ #[ cfg( all( not( target_os = "redox" ) , target_env = "musl" ) ) ]
1011+ fn test_ttyname_invalid_fd ( ) {
1012+ assert_eq ! ( ttyname( -1 ) , Err ( Error :: Sys ( Errno :: ENOTTY ) ) ) ;
1013+ }
0 commit comments