mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
yes: match with GNU's strace behaviour (#12717)
This commit is contained in:
+8
-10
@@ -111,23 +111,21 @@ pub fn exec(bytes: &[u8]) -> io::Result<()> {
|
||||
let stdout = rustix::stdio::stdout();
|
||||
// improve throughput
|
||||
let _ = rustix::pipe::fcntl_setpipe_size(stdout, MAX_ROOTLESS_PIPE_SIZE);
|
||||
// don't show any error from fast-path and fallback to write for proper message
|
||||
// GNU catches all strace injections for zero-copy syscalls except for 1st one (checking support of it)
|
||||
// tee() cannot control offset. We can do tee only if original bytes.len() is multiple of PIPE_BUF,
|
||||
// but it is slower than mixing splice even it reduces syscalls...
|
||||
let bytes_len = bytes.len();
|
||||
if let Ok((p_read, mut p_write)) = pipe::<true>()
|
||||
&& p_write.write_all(bytes).is_ok()
|
||||
&& let Ok((broker_read, broker_write)) = pipe::<true>()
|
||||
&& Ok(bytes_len) == tee(&p_read, &broker_write, MAX_ROOTLESS_PIPE_SIZE)
|
||||
&& uucore::pipes::drain_pipe(&broker_read, &stdout, bytes_len)?.is_ok()
|
||||
{
|
||||
'splice: while let Ok(mut remain) = tee(&p_read, &broker_write, MAX_ROOTLESS_PIPE_SIZE) {
|
||||
debug_assert!(remain == bytes.len(), "splice() should cleanup pipe");
|
||||
// fallback from tee() is possible since we did not send anything to stdout yet
|
||||
while let Ok(mut remain) = tee(&p_read, &broker_write, MAX_ROOTLESS_PIPE_SIZE) {
|
||||
debug_assert!(remain == bytes_len, "splice should cleanup pipe");
|
||||
while remain > 0 {
|
||||
if let Ok(s) = splice(&broker_read, &stdout, remain) {
|
||||
remain -= s;
|
||||
} else {
|
||||
// avoid output breakage with reduced remain even if it would not happen
|
||||
RawWriter(stdout).write_all(&bytes[bytes.len() - remain..])?;
|
||||
break 'splice;
|
||||
}
|
||||
remain -= splice(&broker_read, &stdout, remain)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user