diff options
| author | bors <bors@rust-lang.org> | 2016-03-10 11:56:29 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-03-10 11:56:29 -0800 |
| commit | c1fb50f5d377a41dd5833e4621e9a14879647503 (patch) | |
| tree | 1267b25a66c4ea40ef1c4e0f268f852291bc236d /src/libstd | |
| parent | 4b87655e69a6d07f03b104caaec80a042ad40bf1 (diff) | |
| parent | c516335815c0bda958d81ca5f964473c212e5a4d (diff) | |
| download | rust-c1fb50f5d377a41dd5833e4621e9a14879647503.tar.gz rust-c1fb50f5d377a41dd5833e4621e9a14879647503.zip | |
Auto merge of #32107 - Stebalien:partial-write, r=alexcrichton
Never return an error after a partial write If LineWriter fails to flush, return the number of bytes written instead of an error. Fixes #32085
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/buffered.rs | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index ccebf3682c2..08877fe9744 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -762,8 +762,10 @@ impl<W: Write> Write for LineWriter<W> { match memchr::memrchr(b'\n', buf) { Some(i) => { let n = try!(self.inner.write(&buf[..i + 1])); - if n != i + 1 { return Ok(n) } - try!(self.inner.flush()); + if n != i + 1 || self.inner.flush().is_err() { + // Do not return errors on partial writes. + return Ok(n); + } self.inner.write(&buf[i + 1..]).map(|i| n + i) } None => self.inner.write(buf), @@ -983,6 +985,34 @@ mod tests { } #[test] + fn test_line_buffer_fail_flush() { + // Issue #32085 + struct FailFlushWriter<'a>(&'a mut Vec<u8>); + + impl<'a> Write for FailFlushWriter<'a> { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.0.extend_from_slice(buf); + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "flush failed")) + } + } + + let mut buf = Vec::new(); + { + let mut writer = LineWriter::new(FailFlushWriter(&mut buf)); + let to_write = b"abc\ndef"; + if let Ok(written) = writer.write(to_write) { + assert!(written < to_write.len(), "didn't flush on new line"); + // PASS + return; + } + } + assert!(buf.is_empty(), "write returned an error but wrote data"); + } + + #[test] fn test_line_buffer() { let mut writer = LineWriter::new(Vec::new()); writer.write(&[0]).unwrap(); |
