@@ -281,37 +281,53 @@ struct Elapsing {
281281
282282impl Elapsing {
283283 async fn event_loop ( & mut self ) -> Result < ExitCode , Error > {
284+ let mut stdout_eof = false ;
285+ let mut stderr_eof = false ;
286+ let mut exit_code = None ;
284287 loop {
288+ if stdout_eof && stderr_eof {
289+ if let Some ( rc) = exit_code {
290+ self . statline . clear ( ) ?;
291+ return Ok ( rc) ;
292+ }
293+ }
285294 tokio:: select! {
286295 _ = self . ticker. tick( ) => {
287296 self . statline. clear( ) ?;
288297 self . statline. print( ) ?;
289298 } ,
290- r = self . pout. next_line( ) => {
299+ r = self . pout. next_line( ) , if !stdout_eof => {
291300 if self . stdout_is_tty {
292301 self . statline. clear( ) ?;
293302 }
294- let line = r. map_err( Error :: ReadStdout ) ?;
295- self . stdout. lock( ) . write_all( & line) . map_err( Error :: Write ) ?;
303+ if let Some ( line) = r. map_err( Error :: ReadStdout ) ? {
304+ self . stdout. lock( ) . write_all( & line) . map_err( Error :: Write ) ?;
305+ } else {
306+ stdout_eof = true ;
307+ }
296308 if self . stdout_is_tty {
297309 self . statline. print( ) ?;
298310 }
299311 }
300- r = self . perr. next_line( ) => {
312+ r = self . perr. next_line( ) , if !stderr_eof => {
301313 self . statline. clear( ) ?;
302- let line = r. map_err( Error :: ReadStderr ) ?;
303- self . stderr. lock( ) . write_all( & line) . map_err( Error :: Write ) ?;
314+ if let Some ( line) = r. map_err( Error :: ReadStderr ) ? {
315+ self . stderr. lock( ) . write_all( & line) . map_err( Error :: Write ) ?;
316+ } else {
317+ stderr_eof = true ;
318+ }
304319 self . statline. print( ) ?;
305320 }
306- r = self . p. wait( ) => {
321+ r = self . p. wait( ) , if exit_code . is_none ( ) => {
307322 self . statline. clear( ) ?;
308323 let rc = r. map_err( Error :: Wait ) ?;
309324 if let Some ( ret) = rc. code( ) {
310325 let ret = u8 :: try_from( ret & 255 ) . unwrap_or( 1 ) ;
311- return Ok ( ExitCode :: from( ret) ) ;
326+ exit_code = Some ( ExitCode :: from( ret) ) ;
312327 } else {
313328 return Err ( Error :: Signal ( rc) ) ;
314329 }
330+ self . statline. print( ) ?;
315331 }
316332 r = tokio:: signal:: ctrl_c( ) => {
317333 if r. is_ok( ) {
@@ -488,14 +504,14 @@ struct NextLine<'a, R> {
488504}
489505
490506impl < R : AsyncRead + Unpin > Future for NextLine < ' _ , R > {
491- type Output = io:: Result < Vec < u8 > > ;
507+ type Output = io:: Result < Option < Vec < u8 > > > ;
492508
493509 fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
494510 loop {
495511 if let Some ( ln) = self . inner . get_line ( ) {
496- return Poll :: Ready ( Ok ( ln ) ) ;
512+ return Poll :: Ready ( Ok ( Some ( ln ) ) ) ;
497513 } else if self . inner . eof {
498- return Poll :: Pending ;
514+ return Poll :: Ready ( Ok ( None ) ) ;
499515 } else {
500516 let mut buf0 = vec ! [ 0u8 ; READ_BUFFER_SIZE ] ;
501517 let mut buf = ReadBuf :: new ( & mut buf0) ;
@@ -649,28 +665,32 @@ mod tests {
649665 mod byte_lines {
650666 use super :: * ;
651667 use std:: io:: Cursor ;
652- use tokio_test:: { assert_pending , io:: Builder , task :: spawn } ;
668+ use tokio_test:: io:: Builder ;
653669
654670 #[ tokio:: test]
655671 async fn many_short_lines ( ) {
656672 let reader = Cursor :: new ( b"Hello!\n I like your code.\n Goodbye!\n " ) ;
657673 let mut lines = ByteLines :: new ( reader) ;
658- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Hello!\n " ) ;
659- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"I like your code.\n " ) ;
660- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Goodbye!\n " ) ;
661- let mut fut = spawn ( lines. next_line ( ) ) ;
662- assert_pending ! ( fut. poll( ) ) ;
674+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Hello!\n " ) ;
675+ assert_eq ! (
676+ lines. next_line( ) . await . unwrap( ) . unwrap( ) ,
677+ b"I like your code.\n "
678+ ) ;
679+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Goodbye!\n " ) ;
680+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) , None ) ;
663681 }
664682
665683 #[ tokio:: test]
666684 async fn many_short_lines_no_final_newline ( ) {
667685 let reader = Cursor :: new ( b"Hello!\n I like your code.\n Goodbye!" ) ;
668686 let mut lines = ByteLines :: new ( reader) ;
669- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Hello!\n " ) ;
670- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"I like your code.\n " ) ;
671- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Goodbye!" ) ;
672- let mut fut = spawn ( lines. next_line ( ) ) ;
673- assert_pending ! ( fut. poll( ) ) ;
687+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Hello!\n " ) ;
688+ assert_eq ! (
689+ lines. next_line( ) . await . unwrap( ) . unwrap( ) ,
690+ b"I like your code.\n "
691+ ) ;
692+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Goodbye!" ) ;
693+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) , None ) ;
674694 }
675695
676696 #[ tokio:: test]
@@ -681,32 +701,35 @@ mod tests {
681701 . read ( b"Bye now!\n " )
682702 . build ( ) ;
683703 let mut lines = ByteLines :: new ( reader) ;
684- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Hello, World!\n " ) ;
685- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Bye now!\n " ) ;
686- let mut fut = spawn ( lines. next_line ( ) ) ;
687- assert_pending ! ( fut. poll( ) ) ;
704+ assert_eq ! (
705+ lines. next_line( ) . await . unwrap( ) . unwrap( ) ,
706+ b"Hello, World!\n "
707+ ) ;
708+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Bye now!\n " ) ;
709+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) , None ) ;
688710 }
689711
690712 #[ tokio:: test]
691713 async fn non_utf8 ( ) {
692714 let reader = Cursor :: new ( b"Hell\xF6 !\n I like your code.\n Goodbye!\n " ) ;
693715 let mut lines = ByteLines :: new ( reader) ;
694- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Hell\xF6 !\n " ) ;
695- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"I like your code.\n " ) ;
696- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Goodbye!\n " ) ;
697- let mut fut = spawn ( lines. next_line ( ) ) ;
698- assert_pending ! ( fut. poll( ) ) ;
716+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Hell\xF6 !\n " ) ;
717+ assert_eq ! (
718+ lines. next_line( ) . await . unwrap( ) . unwrap( ) ,
719+ b"I like your code.\n "
720+ ) ;
721+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Goodbye!\n " ) ;
722+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) , None ) ;
699723 }
700724
701725 #[ tokio:: test]
702726 async fn strip_cr ( ) {
703727 let reader = Cursor :: new ( b"Hello!\r \n Goodbye!\n " ) ;
704728 let mut lines = ByteLines :: new ( reader) ;
705729 lines. strip_cr = true ;
706- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Hello!\n " ) ;
707- assert_eq ! ( lines. next_line( ) . await . unwrap( ) , b"Goodbye!\n " ) ;
708- let mut fut = spawn ( lines. next_line ( ) ) ;
709- assert_pending ! ( fut. poll( ) ) ;
730+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Hello!\n " ) ;
731+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) . unwrap( ) , b"Goodbye!\n " ) ;
732+ assert_eq ! ( lines. next_line( ) . await . unwrap( ) , None ) ;
710733 }
711734 }
712735}
0 commit comments