about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-07-19 01:20:50 -0700
committerGitHub <noreply@github.com>2016-07-19 01:20:50 -0700
commit92400cf8dcf411ce7e70ab2960639977d46d5b01 (patch)
tree0dc3777e4db3af07ca9c578d2ec60dc37faa0fee /src
parent8052f73d7b53d55781e49fc36e109312293a31d5 (diff)
parente7d423a3bf599b8e235d25511e807e6bf981c020 (diff)
downloadrust-92400cf8dcf411ce7e70ab2960639977d46d5b01.tar.gz
rust-92400cf8dcf411ce7e70ab2960639977d46d5b01.zip
Auto merge of #33974 - habnabit:eintr-retry-for-read-iterators, r=alexcrichton
Retry on EINTR in Bytes and Chars.

>Since Bytes and Chars called directly into Read::read, they didn't use any of the retrying wrappers. This allows both iterator types to retry.
Diffstat (limited to 'src')
-rw-r--r--src/libstd/io/mod.rs29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index a058337a50a..d5b255ee573 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1522,6 +1522,18 @@ impl<T: BufRead> BufRead for Take<T> {
     }
 }
 
+fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
+    let mut buf = [0];
+    loop {
+        return match reader.read(&mut buf) {
+            Ok(0) => None,
+            Ok(..) => Some(Ok(buf[0])),
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+            Err(e) => Some(Err(e)),
+        };
+    }
+}
+
 /// An iterator over `u8` values of a reader.
 ///
 /// This struct is generally created by calling [`bytes()`][bytes] on a reader.
@@ -1538,12 +1550,7 @@ impl<R: Read> Iterator for Bytes<R> {
     type Item = Result<u8>;
 
     fn next(&mut self) -> Option<Result<u8>> {
-        let mut buf = [0];
-        match self.inner.read(&mut buf) {
-            Ok(0) => None,
-            Ok(..) => Some(Ok(buf[0])),
-            Err(e) => Some(Err(e)),
-        }
+        read_one_byte(&mut self.inner)
     }
 }
 
@@ -1579,11 +1586,10 @@ impl<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
     fn next(&mut self) -> Option<result::Result<char, CharsError>> {
-        let mut buf = [0];
-        let first_byte = match self.inner.read(&mut buf) {
-            Ok(0) => return None,
-            Ok(..) => buf[0],
-            Err(e) => return Some(Err(CharsError::Other(e))),
+        let first_byte = match read_one_byte(&mut self.inner) {
+            None => return None,
+            Some(Ok(b)) => b,
+            Some(Err(e)) => return Some(Err(CharsError::Other(e))),
         };
         let width = core_str::utf8_char_width(first_byte);
         if width == 1 { return Some(Ok(first_byte as char)) }
@@ -1595,6 +1601,7 @@ impl<R: Read> Iterator for Chars<R> {
                 match self.inner.read(&mut buf[start..width]) {
                     Ok(0) => return Some(Err(CharsError::NotUtf8)),
                     Ok(n) => start += n,
+                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                     Err(e) => return Some(Err(CharsError::Other(e))),
                 }
             }