diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 226c43a7ceb..e458bf3e081 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -481,9 +481,7 @@ fn print_fast(handle: &mut InputHandle) -> CatResult<()> { let mut stdout = stdout; // Try to use the splice() system call for faster writing. If it works, we're done. #[cfg(any(target_os = "linux", target_os = "android"))] - if uucore::pipes::splice_unbounded_auto(&handle.reader, &mut stdout)?.is_ok() - && !uucore::pipes::might_fuse(&handle.reader) - { + if uucore::pipes::splice_unbounded_auto(&handle.reader, &mut stdout)?.is_ok() { return Ok(()); } diff --git a/src/uucore/src/lib/features/pipes.rs b/src/uucore/src/lib/features/pipes.rs index 076e4fbdd59..443e290278a 100644 --- a/src/uucore/src/lib/features/pipes.rs +++ b/src/uucore/src/lib/features/pipes.rs @@ -75,13 +75,6 @@ pub fn drain_pipe(pipe: &PipeReader, dest: &impl AsFd, len: usize) -> PipeRes { Ok(Ok(())) } -/// check that source is FUSE -/// we fallback to read() at FUSE -#[inline] -pub fn might_fuse(source: &impl AsFd) -> bool { - rustix::fs::fstatfs(source).map_or(true, |stats| stats.f_type == 0x6573_5546) // FUSE magic number, too many platform specific clippy warning with const -} - /// splice all of source to dest /// returns Ok(()) at end of file #[inline] @@ -143,59 +136,52 @@ pub fn send_n_bytes(input: impl AsFd, target: impl AsFd, n: u64) -> std::io::Res } let mut n = n; let mut bytes_written: u64 = 0; - let succeed_or_fuse = loop { + loop { if n == 0 { // avoid unnecessary syscall return Ok(bytes_written); } match splice(&input, &target, n as usize) { - Ok(0) => break true, + Ok(0) => return Ok(bytes_written), Ok(s) => { n -= s as u64; bytes_written += s as u64; } - _ => break false, // input or output is not pipe + _ => break, // input or output is not pipe } - }; - let succeed_or_fuse = succeed_or_fuse - || if let Some((broker_r, broker_w)) = PIPE_CACHE - .get_or_init(|| { - // use std::io::pipe to avoid unnecessary fcntl - let pair = std::io::pipe().ok()?; - if pipe_size > KERNEL_DEFAULT_PIPE_SIZE { - let _ = fcntl_setpipe_size(&pair.0, pipe_size); - } - Some(pair) - }) - .as_ref() - { - // todo: create fn splice_bounded_broker - loop { - if n == 0 { - return Ok(bytes_written); - } - match splice(&input, &broker_w, n as usize) { - Ok(0) => break true, - Ok(s) => { - n -= s as u64; - bytes_written += s as u64; - if drain_pipe(broker_r, &target, s)?.is_err() { - break false; - } + } + if let Some((broker_r, broker_w)) = PIPE_CACHE + .get_or_init(|| { + // use std::io::pipe to avoid unnecessary fcntl + let pair = std::io::pipe().ok()?; + if pipe_size > KERNEL_DEFAULT_PIPE_SIZE { + let _ = fcntl_setpipe_size(&pair.0, pipe_size); + } + Some(pair) + }) + .as_ref() + { + // todo: create fn splice_bounded_broker + loop { + if n == 0 { + return Ok(bytes_written); + } + match splice(&input, &broker_w, n as usize) { + Ok(0) => return Ok(bytes_written), + Ok(s) => { + n -= s as u64; + bytes_written += s as u64; + if drain_pipe(broker_r, &target, s)?.is_err() { + break; } - _ => break false, } + _ => break, } - } else { - false - }; - // do not always fallback to write for fuse, or 2 Ctrl+D is required to exit on tty - // todo: move fuse patch to callers - if !succeed_or_fuse || might_fuse(&input) { - // remove buffering from this fallback by RawReader, or order of output would be wrong with multiple input - bytes_written += std::io::copy(&mut RawReader(input).take(n), &mut RawWriter(target))?; + } } + // fallback. remove buffering from this fallback by RawReader, or order of output would be wrong with multiple input + bytes_written += std::io::copy(&mut RawReader(input).take(n), &mut RawWriter(target))?; Ok(bytes_written) }