Skip to content

Commit 7a5d3ab

Browse files
committed
Avoid writes without any data in Write::write_all_vectored
Previously, when non-empty sequence of empty IoSlices have been provided to `Write::write_all_vectored`, the buffers would be written as is with `Write::write_vectored` and subsequently the return value `Ok(0)` would be misinterpreted as an error. Avoid writes without any data by advancing the buffers first. This matches the documented behaviour of `Write::write_all_vectored` and is analogous to what happens in `Write::write_all`.
1 parent 461707c commit 7a5d3ab

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

src/libstd/io/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@
251251

252252
use crate::cmp;
253253
use crate::fmt;
254-
use crate::mem;
255254
use crate::memchr;
256255
use crate::ops::{Deref, DerefMut};
257256
use crate::ptr;
@@ -1435,12 +1434,15 @@ pub trait Write {
14351434
/// ```
14361435
#[unstable(feature = "write_all_vectored", issue = "70436")]
14371436
fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
1437+
// Guarantee that bufs is empty if it contains no data,
1438+
// to avoid calling write_vectored if there is no data to be written.
1439+
bufs = IoSlice::advance(bufs, 0);
14381440
while !bufs.is_empty() {
14391441
match self.write_vectored(bufs) {
14401442
Ok(0) => {
14411443
return Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"));
14421444
}
1443-
Ok(n) => bufs = IoSlice::advance(mem::take(&mut bufs), n),
1445+
Ok(n) => bufs = IoSlice::advance(bufs, n),
14441446
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
14451447
Err(e) => return Err(e),
14461448
}
@@ -2958,6 +2960,7 @@ mod tests {
29582960
#[rustfmt::skip] // Becomes unreadable otherwise.
29592961
let tests: Vec<(_, &'static [u8])> = vec![
29602962
(vec![], &[]),
2963+
(vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
29612964
(vec![IoSlice::new(&[1])], &[1]),
29622965
(vec![IoSlice::new(&[1, 2])], &[1, 2]),
29632966
(vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),

0 commit comments

Comments
 (0)