@@ -9,7 +9,7 @@ use signal_hook::low_level::pipe;
99
1010use crate :: event:: Event ;
1111use crate :: event:: timeout:: PollTimeout ;
12- use filedescriptor:: { POLLIN , poll, pollfd} ;
12+ use filedescriptor:: { POLLERR , POLLHUP , POLLIN , poll, pollfd} ;
1313
1414#[ cfg( feature = "event-stream" ) ]
1515use crate :: event:: sys:: Waker ;
@@ -85,12 +85,19 @@ impl UnixInternalEventSource {
8585///
8686/// Similar to `std::io::Read::read_to_end`, except this function
8787/// only fills the given buffer and does not read beyond that.
88- fn read_complete ( fd : & FileDesc , buf : & mut [ u8 ] ) -> io:: Result < usize > {
88+ /// It returns `None` for `WouldBlock` and an error when the input closes.
89+ fn read_complete ( fd : & FileDesc , buf : & mut [ u8 ] ) -> io:: Result < Option < usize > > {
8990 loop {
9091 match fd. read ( buf) {
91- Ok ( x) => return Ok ( x) ,
92+ Ok ( 0 ) => {
93+ return Err ( io:: Error :: new (
94+ io:: ErrorKind :: UnexpectedEof ,
95+ "input source closed" ,
96+ ) ) ;
97+ }
98+ Ok ( read_count) => return Ok ( Some ( read_count) ) ,
9299 Err ( e) => match e. kind ( ) {
93- io:: ErrorKind :: WouldBlock => return Ok ( 0 ) ,
100+ io:: ErrorKind :: WouldBlock => return Ok ( None ) ,
94101 io:: ErrorKind :: Interrupted => continue ,
95102 _ => return Err ( e) ,
96103 } ,
@@ -144,31 +151,30 @@ impl EventSource for UnixInternalEventSource {
144151 Ok ( _) => ( ) ,
145152 } ;
146153 if fds[ 0 ] . revents & POLLIN != 0 {
147- loop {
148- let read_count = read_complete ( & self . tty , & mut self . tty_buffer ) ?;
149- if read_count > 0 {
150- self . parser . advance (
151- & self . tty_buffer [ ..read_count] ,
152- read_count == TTY_BUFFER_SIZE ,
153- ) ;
154- }
154+ while let Some ( read_count) = read_complete ( & self . tty , & mut self . tty_buffer ) ? {
155+ self . parser . advance (
156+ & self . tty_buffer [ ..read_count] ,
157+ read_count == TTY_BUFFER_SIZE ,
158+ ) ;
155159
156160 if let Some ( event) = self . parser . next ( ) {
157161 return Ok ( Some ( event) ) ;
158162 }
159-
160- if read_count == 0 {
161- break ;
162- }
163163 }
164164 }
165+ if fds[ 0 ] . revents & ( POLLERR | POLLHUP ) != 0 {
166+ return Err ( io:: Error :: new (
167+ io:: ErrorKind :: UnexpectedEof ,
168+ "input source closed" ,
169+ ) ) ;
170+ }
165171 if fds[ 1 ] . revents & POLLIN != 0 {
166172 #[ cfg( feature = "libc" ) ]
167173 let fd = FileDesc :: new ( self . winch_signal_receiver . as_raw_fd ( ) , false ) ;
168174 #[ cfg( not( feature = "libc" ) ) ]
169175 let fd = FileDesc :: Borrowed ( self . winch_signal_receiver . as_fd ( ) ) ;
170176 // drain the pipe
171- while read_complete ( & fd, & mut [ 0 ; 1024 ] ) ? != 0 { }
177+ while read_complete ( & fd, & mut [ 0 ; 1024 ] ) ?. is_some ( ) { }
172178 // TODO Should we remove tput?
173179 //
174180 // This can take a really long time, because terminal::size can
@@ -188,7 +194,7 @@ impl EventSource for UnixInternalEventSource {
188194 #[ cfg( not( feature = "libc" ) ) ]
189195 let fd = FileDesc :: Borrowed ( self . wake_pipe . receiver . as_fd ( ) ) ;
190196 // drain the pipe
191- while read_complete ( & fd, & mut [ 0 ; 1024 ] ) ? != 0 { }
197+ while read_complete ( & fd, & mut [ 0 ; 1024 ] ) ?. is_some ( ) { }
192198
193199 return Err ( std:: io:: Error :: new (
194200 std:: io:: ErrorKind :: Interrupted ,
0 commit comments