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
/// 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
/// pipe.
#[inline]
/// Move exactly `num_bytes` bytes from `read_fd` to `write_fd`.
///
/// Panics if not enough bytes can be read.
fn copy_exact(read_fd: RawFd, write_fd: RawFd, num_bytes: usize) -> nix::Result<()> {
let mut left = num_bytes;
let mut buf = [0; BUF_SIZE];
loop {
let read = unistd::read(read_fd, &mut buf[..left])?;
let written = unistd::write(write_fd, &buf[..read])?;
left -= written;
if left == 0 {
break;
while left > 0 {
let read = unistd::read(read_fd, &mut buf)?;
assert_ne!(read, 0, "unexpected end of pipe");
let mut written = 0;
while written < read {
match unistd::write(write_fd, &buf[written..read])? {
0 => panic!(),
n => written += n,
}
}
left -= read;
}
Ok(())
}