From ab130c431cf50b5a559f80070f4fcf1d886c5fdd Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 23 Feb 2022 14:36:16 +0100 Subject: [PATCH 1/2] fix(io): handle missing source in stdin Currently `io::stdin()` when used with `lines().fuse()` from `futures`, will panic on the first poll. This adds a test for this case, as well as a potential fix. --- glommio/src/io/buffered_file_stream.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/glommio/src/io/buffered_file_stream.rs b/glommio/src/io/buffered_file_stream.rs index fe6571776..c7cde4e5b 100644 --- a/glommio/src/io/buffered_file_stream.rs +++ b/glommio/src/io/buffered_file_stream.rs @@ -654,7 +654,12 @@ impl AsyncBufRead for Stdin { ) -> Poll> { match self.source.take() { Some(source) => { - let res = source.result().unwrap(); + let res = match source.result() { + Some(res) => res, + None => { + return Poll::Pending; + } + }; match res { Err(x) => Poll::Ready(Err(x)), Ok(sz) => { @@ -691,9 +696,9 @@ impl AsyncBufRead for Stdin { #[cfg(test)] mod test { use super::*; - use crate::test_utils::make_test_directories; + use crate::{test_utils::make_test_directories, GlommioError}; use futures_lite::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, StreamExt}; - use std::io::ErrorKind; + use std::{io::ErrorKind, time::Duration}; macro_rules! read_test { ( $name:ident, $dir:ident, $kind:ident, $file:ident, $file_size:ident: $size:tt, $code:block) => { @@ -982,4 +987,19 @@ mod test { reader.close().await.unwrap(); writer.close().await.unwrap(); }); + + #[test] + fn test_stdin_fuse() { + use futures::StreamExt; + + test_executor!(async move { + let mut si = StreamExt::fuse(stdin().lines()); + let fut = crate::timer::timeout(Duration::from_millis(5), async move { + si.select_next_some() + .await + .map_err(|err| GlommioError::IoError(err)) + }); + assert!(matches!(fut.await, Err(GlommioError::TimedOut(_)))); + }); + } } From f27fa233bb52b8dbb1057240478e6db7df9146ac Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 23 Feb 2022 14:51:29 +0100 Subject: [PATCH 2/2] fixup: try making test work on ci --- glommio/src/io/buffered_file_stream.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/glommio/src/io/buffered_file_stream.rs b/glommio/src/io/buffered_file_stream.rs index c7cde4e5b..704028aa6 100644 --- a/glommio/src/io/buffered_file_stream.rs +++ b/glommio/src/io/buffered_file_stream.rs @@ -994,11 +994,12 @@ mod test { test_executor!(async move { let mut si = StreamExt::fuse(stdin().lines()); - let fut = crate::timer::timeout(Duration::from_millis(5), async move { - si.select_next_some() - .await - .map_err(|err| GlommioError::IoError(err)) - }); + let fut = + crate::timer::timeout(Duration::from_millis(1), async move { + StreamExt::next(&mut si).await.ok_or(GlommioError::IoError( + std::io::Error::new(std::io::ErrorKind::BrokenPipe, "stdin closed"), + )) + }); assert!(matches!(fut.await, Err(GlommioError::TimedOut(_)))); }); }