From d8eb4e2214bec6681c519cce2c80024a722fc5d8 Mon Sep 17 00:00:00 2001 From: GiM Date: Sun, 6 Oct 2024 11:31:31 +0200 Subject: [PATCH] cat: fix #5186 by adding explicit flush. (#5256) * fix #5186 by adding explicit flush. * make test machine-independent --------- Co-authored-by: Sylvestre Ledru Co-authored-by: Daniel Hofstetter --- src/uu/cat/src/cat.rs | 7 +++++++ tests/by-util/test_cat.rs | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 9aeb3ca15..544af3138 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -467,6 +467,13 @@ fn write_fast(handle: &mut InputHandle) -> CatResult<()> { } stdout_lock.write_all(&buf[..n])?; } + + // If the splice() call failed and there has been some data written to + // stdout via while loop above AND there will be second splice() call + // that will succeed, data pushed through splice will be output before + // the data buffered in stdout.lock. Therefore additional explicit flush + // is required here. + stdout_lock.flush()?; Ok(()) } diff --git a/tests/by-util/test_cat.rs b/tests/by-util/test_cat.rs index 898325187..d9be69436 100644 --- a/tests/by-util/test_cat.rs +++ b/tests/by-util/test_cat.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore NOFILE nonewline +// spell-checker:ignore NOFILE nonewline cmdline #[cfg(not(windows))] use crate::common::util::vec_of_size; @@ -529,6 +529,21 @@ fn test_dev_full_show_all() { proc.kill(); } +// For some reason splice() on first of those files fails, resulting in +// fallback inside `write_fast`, the other splice succeeds, in effect +// without additional flush output gets reversed. +#[test] +#[cfg(target_os = "linux")] +fn test_write_fast_fallthrough_uses_flush() { + const PROC_INIT_CMDLINE: &str = "/proc/1/cmdline"; + let cmdline = std::fs::read_to_string(PROC_INIT_CMDLINE).unwrap(); + + new_ucmd!() + .args(&[PROC_INIT_CMDLINE, "alpha.txt"]) + .succeeds() + .stdout_only(format!("{cmdline}abcde\nfghij\nklmno\npqrst\nuvwxyz\n")); // spell-checker:disable-line +} + #[test] #[cfg(unix)] #[ignore]