Skip to content

head: port splice fast-path for -c as seen as wc -c #11491

@oech3

Description

@oech3

I noticed that we have

/// This is a Linux-specific function to count the number of bytes using the
/// `splice` system call, which is faster than using `read`.
///
/// On error it returns the number of bytes it did manage to read, since the
/// caller will fall back to a simpler method.
#[inline]
#[cfg(any(target_os = "linux", target_os = "android"))]
fn count_bytes_using_splice(fd: &impl AsFd) -> Result<usize, usize> {
let null_file = OpenOptions::new()
.write(true)
.open("/dev/null")
.map_err(|_| 0_usize)?;
let null_rdev = stat::fstat(null_file.as_fd()).map_err(|_| 0_usize)?.st_rdev as libc::dev_t;
if (libc::major(null_rdev), libc::minor(null_rdev)) != (1, 3) {
// This is not a proper /dev/null, writing to it is probably bad
// Bit of an edge case, but it has been known to happen
return Err(0);
}
let (pipe_rd, pipe_wr) = pipe().map_err(|_| 0_usize)?;
let mut byte_count = 0;
loop {
match splice(fd, &pipe_wr, SPLICE_SIZE) {
Ok(0) => break,
Ok(res) => {
byte_count += res;
// Silent the warning as we want to the error message
#[allow(clippy::question_mark)]
if splice_exact(&pipe_rd, &null_file, res).is_err() {
return Err(byte_count);
}
}
Err(_) => return Err(byte_count),
}
}
Ok(byte_count)
}

I think head -c can splice too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions