Skip to content

Commit c48b5fe

Browse files
oech3sylvestre
authored andcommitted
wc: avoid pipe() if input is pipe
1 parent 4011e6d commit c48b5fe

1 file changed

Lines changed: 23 additions & 14 deletions

File tree

src/uu/wc/src/count_fast.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,33 @@ const BUF_SIZE: usize = 64 * 1024;
4040
#[cfg(any(target_os = "linux", target_os = "android"))]
4141
fn count_bytes_using_splice(fd: &impl AsFd) -> Result<usize, usize> {
4242
let null_file = uucore::pipes::dev_null().ok_or(0_usize)?;
43-
// todo: avoid generating broker if input is pipe (fcntl_setpipe_size succeed) and directly splice() to /dev/null to save RAM usage
44-
let (pipe_rd, pipe_wr) = pipe().map_err(|_| 0_usize)?;
45-
4643
let mut byte_count = 0;
47-
// improve throughput from pipe
48-
let _ = rustix::pipe::fcntl_setpipe_size(fd, MAX_ROOTLESS_PIPE_SIZE);
49-
loop {
50-
match splice(fd, &pipe_wr, MAX_ROOTLESS_PIPE_SIZE) {
51-
Ok(0) => break,
52-
Ok(res) => {
53-
byte_count += res;
54-
// Silent the warning as we want to the error message
55-
if splice_exact(&pipe_rd, &null_file, res).is_err() {
56-
return Err(byte_count);
44+
if let Ok(res) = splice(fd, &null_file, MAX_ROOTLESS_PIPE_SIZE) {
45+
byte_count += res;
46+
// no need to increase pipe size of input fd since
47+
// - sender with splice probably increased size already
48+
// - sender without splice is bottleneck of our wc -c
49+
loop {
50+
match splice(fd, &null_file, MAX_ROOTLESS_PIPE_SIZE) {
51+
Ok(0) => break,
52+
Ok(res) => byte_count += res,
53+
Err(_) => return Err(byte_count),
54+
}
55+
}
56+
} else if let Ok((pipe_rd, pipe_wr)) = pipe() {
57+
// input is not pipe. needs broker to use splice() with additional cost
58+
loop {
59+
match splice(fd, &pipe_wr, MAX_ROOTLESS_PIPE_SIZE) {
60+
Ok(0) => break,
61+
Ok(res) => {
62+
byte_count += res;
63+
splice_exact(&pipe_rd, &null_file, res).map_err(|_| byte_count)?;
5764
}
65+
Err(_) => return Err(byte_count),
5866
}
59-
Err(_) => return Err(byte_count),
6067
}
68+
} else {
69+
return Ok(0_usize);
6170
}
6271

6372
Ok(byte_count)

0 commit comments

Comments
 (0)