1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-09-15 19:36:16 +00:00

cat: Do not assume complete writes

This commit is contained in:
Jan Verbeek 2021-08-27 20:10:28 +02:00
parent c1079e0b1c
commit d002810a47

View file

@ -44,21 +44,23 @@ pub(super) fn write_fast_using_splice<R: FdReadable>(
} }
} }
/// Caller must ensure that `num_bytes <= BUF_SIZE`, otherwise this function /// Move exactly `num_bytes` bytes from `read_fd` to `write_fd`.
/// will panic. The way we use this function in `write_fast_using_splice` ///
/// above is safe because `splice` is set to write at most `BUF_SIZE` to the /// Panics if not enough bytes can be read.
/// pipe.
#[inline]
fn copy_exact(read_fd: RawFd, write_fd: RawFd, num_bytes: usize) -> nix::Result<()> { fn copy_exact(read_fd: RawFd, write_fd: RawFd, num_bytes: usize) -> nix::Result<()> {
let mut left = num_bytes; let mut left = num_bytes;
let mut buf = [0; BUF_SIZE]; let mut buf = [0; BUF_SIZE];
loop { while left > 0 {
let read = unistd::read(read_fd, &mut buf[..left])?; let read = unistd::read(read_fd, &mut buf)?;
let written = unistd::write(write_fd, &buf[..read])?; assert_ne!(read, 0, "unexpected end of pipe");
left -= written; let mut written = 0;
if left == 0 { while written < read {
break; match unistd::write(write_fd, &buf[written..read])? {
0 => panic!(),
n => written += n,
}
} }
left -= read;
} }
Ok(()) Ok(())
} }