-
Couldn't load subscription status.
- Fork 13.9k
Description
LineWriter can return an error after a partial write if flushing the inner BufWriter fails (
rust/src/libstd/io/buffered.rs
Line 766 in cb343c3
| try!(self.inner.flush()); |
Ok(bytes_written), ignoring the error.
OLD REPORT:
I originally thought this problem was systematic so I audited stdlib. Apparently it isn't... See below.
The write trait guarantees:
If an error is returned then no bytes in the buffer were written to this writer.
However, this is violated all over stdlib. For example, if "abc\nde" is written to a LineWriter, the LineWriter could write "abc", try to flush, and then return an error due to a failed flush. However, "abc" has been written violating the spec.
IMO, the solution is to return Ok(amount_written) for partial writes and drop the error (if any). This should be safe because of write's write-xor-error guarantee. If the error was transient, the caller never needs to know. Otherwise, they will will learn of it on the next write.
Here's everything in the stdlib that implements write (and should be audited):
-
Sinkinlibrustdoc/test.rs -
Sinkinlibstd/io/util.rs -
&'a mut Winlibstd/io/impls.rs -
Box<W>inlibstd/io/impls.rs -
&'a mut [u8]inlibstd/io/impls.rs -
Vec<u8>inlibstd/io/impls.rs -
Cursor<&'a mut [u8]>inlibstd/io/cursor.rs -
Cursor<Vec<u8>>inlibstd/io/cursor.rs -
Cursor<Box<[u8]>>inlibstd/io/cursor.rs -
StdoutRawinlibstd/io/stdio.rs -
StderrRawinlibstd/io/stdio.rs -
Maybe<W>inlibstd/io/stdio.rs -
Stdoutinlibstd/io/stdio.rs -
StdoutLock<'a>inlibstd/io/stdio.rs -
Stderrinlibstd/io/stdio.rs -
StderrLock<'a>inlibstd/io/stdio.rs -
BufWriter<W>inlibstd/io/buffered.rs -
LineWriter<W>inlibstd/io/buffered.rs(buggy) -
Broadcast<T, U>inlibstd/io/mod.rs(buggy but unfixable and deprecated). -
TcpStreaminlibstd/net/tcp.rs -
&'a TcpStreaminlibstd/net/tcp.rs -
Stderrinlibstd/sys/unix/stdio.rs -
Stderrinlibstd/sys/windows/stdio.rs(panics on partial write) -
ChildStdininlibstd/process.rs -
Fileinlibstd/fs.rs -
&'a Fileinlibstd/fs.rs