Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions src/uucore/src/lib/features/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,18 @@ pub fn might_fuse(source: &impl AsFd) -> bool {
}

/// splice all of source to dest
/// return true if we need read/write fallback
/// fails if one of in/output should be pipe
/// returns Ok(()) at end of file
#[inline]
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> std::io::Result<bool> {
pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io::Result<()> {
// improve throughput
// todo: avoid fcntl overhead for small input, but don't fcntl inside of the loop
// no need to increase pipe size of input fd since
// - sender with splice probably increased size already
// - sender without splice is bottleneck
let _ = fcntl_setpipe_size(&mut *dest, MAX_ROOTLESS_PIPE_SIZE);
loop {
match splice(&source, &dest, MAX_ROOTLESS_PIPE_SIZE) {
Ok(1..) => {}
Ok(0) => return Ok(false),
Err(_) => return Ok(true),
}
}
while splice(&source, &dest, MAX_ROOTLESS_PIPE_SIZE)? > 0 {}
Ok(())
}

/// force-splice source to dest even both of them are not pipe
Expand Down Expand Up @@ -159,7 +153,7 @@ where
{
// use splice to check that input or output is pipe which is efficient
let fallback = match splice(&source, dest, MAX_ROOTLESS_PIPE_SIZE) {
Ok(_) => splice_unbounded(source, dest)?,
Ok(_) => splice_unbounded(source, dest).is_err(),
_ => splice_unbounded_broker(source, dest)?,
};
Ok(fallback)
Expand Down
Loading