|
1 | 1 | use std::{ |
2 | 2 | ffi::OsStr, |
3 | 3 | fs::{self, Permissions}, |
4 | | - io::{Error, ErrorKind, IoSlice, Read as _, Result, Write as _}, |
| 4 | + io::{Error, ErrorKind, IoSlice, Read as _, Result, Write}, |
5 | 5 | os::{ |
6 | 6 | fd::{AsFd, BorrowedFd}, |
7 | 7 | unix::{ |
@@ -170,13 +170,13 @@ impl Client { |
170 | 170 | }; |
171 | 171 | let packed_len_buf = packed_len.as_bytes(); |
172 | 172 |
|
173 | | - let io_slice = &[ |
| 173 | + let mut io_slice = [ |
174 | 174 | IoSlice::new(&amount_buf), |
175 | 175 | IoSlice::new(&packed_len_buf), |
176 | 176 | IoSlice::new(bytes), |
177 | 177 | ]; |
178 | 178 |
|
179 | | - _ = stream.write_vectored(io_slice)?; |
| 179 | + write_all_vectored(&mut stream, &mut io_slice)?; |
180 | 180 |
|
181 | 181 | Ok(Self(stream)) |
182 | 182 | } |
@@ -207,6 +207,28 @@ impl Client { |
207 | 207 | } |
208 | 208 | } |
209 | 209 |
|
| 210 | +// FIXME: remove this after `Write::write_all_vectored` stablize |
| 211 | +// https://doc.rust-lang.org/1.93.1/src/std/io/mod.rs.html#1937-1952 |
| 212 | +fn write_all_vectored<W: Write>(write: &mut W, mut bufs: &mut [IoSlice<'_>]) -> Result<()> { |
| 213 | + // Guarantee that bufs is empty if it contains no data, |
| 214 | + // to avoid calling write_vectored if there is no data to be written. |
| 215 | + IoSlice::advance_slices(&mut bufs, 0); |
| 216 | + while !bufs.is_empty() { |
| 217 | + match write.write_vectored(bufs) { |
| 218 | + Ok(0) => { |
| 219 | + return Err(Error::new( |
| 220 | + ErrorKind::WriteZero, |
| 221 | + "failed to write whole buffer", |
| 222 | + )); |
| 223 | + } |
| 224 | + Ok(n) => IoSlice::advance_slices(&mut bufs, n), |
| 225 | + Err(e) if e.kind() == ErrorKind::Interrupted => {} |
| 226 | + Err(e) => return Err(e), |
| 227 | + } |
| 228 | + } |
| 229 | + Ok(()) |
| 230 | +} |
| 231 | + |
210 | 232 | #[cfg(test)] |
211 | 233 | mod tests { |
212 | 234 | use std::{ |
|
0 commit comments