@@ -29,6 +29,15 @@ pub fn is_a_color_terminal(out: &Term) -> bool {
2929 }
3030}
3131
32+ pub fn c_result < F : FnOnce ( ) -> libc:: c_int > ( f : F ) -> io:: Result < ( ) > {
33+ let res = f ( ) ;
34+ if res != 0 {
35+ Err ( io:: Error :: last_os_error ( ) )
36+ } else {
37+ Ok ( ( ) )
38+ }
39+ }
40+
3241#[ inline]
3342pub fn terminal_size ( ) -> Option < ( u16 , u16 ) > {
3443 terminal_size:: terminal_size ( ) . map ( |x| ( ( x. 1 ) . 0 , ( x. 0 ) . 0 ) )
@@ -48,10 +57,12 @@ pub fn read_secure() -> io::Result<String> {
4857 }
4958 } ;
5059
51- let mut termios = termios:: Termios :: from_fd ( fd) ?;
60+ let mut termios = core:: mem:: MaybeUninit :: uninit ( ) ;
61+ c_result ( || unsafe { libc:: tcgetattr ( fd, termios. as_mut_ptr ( ) ) } ) ?;
62+ let mut termios = unsafe { termios. assume_init ( ) } ;
5263 let original = termios;
53- termios. c_lflag &= !termios :: ECHO ;
54- termios :: tcsetattr ( fd, termios :: TCSAFLUSH , & termios) ?;
64+ termios. c_lflag &= !libc :: ECHO ;
65+ c_result ( || unsafe { libc :: tcsetattr ( fd, libc :: TCSAFLUSH , & termios) } ) ?;
5566 let mut rv = String :: new ( ) ;
5667
5768 let read_rv = if let Some ( mut f) = f_tty {
@@ -60,7 +71,7 @@ pub fn read_secure() -> io::Result<String> {
6071 io:: stdin ( ) . read_line ( & mut rv)
6172 } ;
6273
63- termios :: tcsetattr ( fd, termios :: TCSAFLUSH , & original) ?;
74+ c_result ( || unsafe { libc :: tcsetattr ( fd, libc :: TCSAFLUSH , & original) } ) ?;
6475
6576 read_rv. map ( |_| {
6677 let len = rv. trim_end_matches ( & [ '\r' , '\n' ] [ ..] ) . len ( ) ;
@@ -80,10 +91,12 @@ pub fn read_single_key() -> io::Result<Key> {
8091 }
8192 } ;
8293 let mut buf = [ 0u8 ; 20 ] ;
83- let mut termios = termios:: Termios :: from_fd ( fd) ?;
94+ let mut termios = core:: mem:: MaybeUninit :: uninit ( ) ;
95+ c_result ( || unsafe { libc:: tcgetattr ( fd, termios. as_mut_ptr ( ) ) } ) ?;
96+ let mut termios = unsafe { termios. assume_init ( ) } ;
8497 let original = termios;
85- termios :: cfmakeraw ( & mut termios) ;
86- termios :: tcsetattr ( fd, termios :: TCSADRAIN , & termios) ?;
98+ unsafe { libc :: cfmakeraw ( & mut termios) } ;
99+ c_result ( || unsafe { libc :: tcsetattr ( fd, libc :: TCSADRAIN , & termios) } ) ?;
87100 let rv = unsafe {
88101 let read = libc:: read ( fd, buf. as_mut_ptr ( ) as * mut libc:: c_void , 1 ) ;
89102 if read < 0 {
@@ -99,9 +112,9 @@ pub fn read_single_key() -> io::Result<Key> {
99112 "read interrupted" ,
100113 ) )
101114 } else {
102- Ok ( key_from_escape_codes ( & buf[ ..( read+ 1 ) as usize ] ) )
115+ Ok ( key_from_escape_codes ( & buf[ ..( read + 1 ) as usize ] ) )
103116 }
104- } else if buf[ 0 ] & 224u8 == 192u8 {
117+ } else if buf[ 0 ] & 224u8 == 192u8 {
105118 // a two byte unicode character
106119 let read = libc:: read ( fd, buf[ 1 ..] . as_mut_ptr ( ) as * mut libc:: c_void , 1 ) ;
107120 if read < 0 {
@@ -114,7 +127,7 @@ pub fn read_single_key() -> io::Result<Key> {
114127 } else {
115128 Ok ( key_from_escape_codes ( & buf[ ..2 as usize ] ) )
116129 }
117- } else if buf[ 0 ] & 240u8 == 224u8 {
130+ } else if buf[ 0 ] & 240u8 == 224u8 {
118131 // a three byte unicode character
119132 let read = libc:: read ( fd, buf[ 1 ..] . as_mut_ptr ( ) as * mut libc:: c_void , 2 ) ;
120133 if read < 0 {
@@ -127,7 +140,7 @@ pub fn read_single_key() -> io::Result<Key> {
127140 } else {
128141 Ok ( key_from_escape_codes ( & buf[ ..3 as usize ] ) )
129142 }
130- } else if buf[ 0 ] & 248u8 == 240u8 {
143+ } else if buf[ 0 ] & 248u8 == 240u8 {
131144 // a four byte unicode character
132145 let read = libc:: read ( fd, buf[ 1 ..] . as_mut_ptr ( ) as * mut libc:: c_void , 3 ) ;
133146 if read < 0 {
@@ -149,7 +162,7 @@ pub fn read_single_key() -> io::Result<Key> {
149162 Ok ( key_from_escape_codes ( & buf[ ..read as usize ] ) )
150163 }
151164 } ;
152- termios :: tcsetattr ( fd, termios :: TCSADRAIN , & original) ?;
165+ c_result ( || unsafe { libc :: tcsetattr ( fd, libc :: TCSADRAIN , & original) } ) ?;
153166
154167 // if the user hit ^C we want to signal SIGINT to outselves.
155168 if let Err ( ref err) = rv {
0 commit comments