Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions .vscode/cspell.dictionaries/workspace.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ uutils

# * function names
execfn
fstatfs
getcwd
setpipe

Expand Down
6 changes: 3 additions & 3 deletions src/uu/cat/src/splice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::{CatResult, FdReadable, InputHandle};
use rustix::io::{read, write};
use std::os::{fd::AsFd, unix::io::AsRawFd};

use uucore::pipes::{MAX_ROOTLESS_PIPE_SIZE, pipe, splice, splice_exact};
use uucore::pipes::{MAX_ROOTLESS_PIPE_SIZE, might_fuse, pipe, splice, splice_exact};

const BUF_SIZE: usize = 1024 * 16;

Expand All @@ -30,15 +30,15 @@ pub(super) fn write_fast_using_splice<R: FdReadable, S: AsRawFd + AsFd>(
loop {
match splice(&handle.reader, &write_fd, MAX_ROOTLESS_PIPE_SIZE) {
Ok(1..) => {}
Ok(0) => return Ok(false),
Ok(0) => return Ok(might_fuse(&handle.reader)),
Err(_) => return Ok(true),
}
}
} else if let Ok((pipe_rd, pipe_wr)) = pipe() {
// both of in/output are not pipe. needs broker to use splice() with additional costs
loop {
match splice(&handle.reader, &pipe_wr, MAX_ROOTLESS_PIPE_SIZE) {
Ok(0) => return Ok(false),
Ok(0) => return Ok(might_fuse(&handle.reader)),
Ok(n) => {
if splice_exact(&pipe_rd, write_fd, n).is_err() {
// If the first splice manages to copy to the intermediate
Expand Down
10 changes: 10 additions & 0 deletions src/uucore/src/lib/features/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ pub fn splice_exact(source: &impl AsFd, target: &impl AsFd, len: usize) -> std::
Ok(())
}

/// check that source is FUSE
/// we fallback to read() at FUSE <https://github.com/uutils/coreutils/issues/9609>
#[inline]
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn might_fuse(source: &impl AsFd) -> bool {
rustix::fs::fstatfs(source)
.map(|stats| stats.f_type == 0x6573_5546) // FUSE magic number, too many platform specific clippy warning with const
.unwrap_or(true)
}

/// Return verified /dev/null
///
/// `splice` to /dev/null is faster than `read` when we skip or count the input which is not able to seek
Expand Down
Loading