cat: fix #5186 by adding explicit flush. (#5256)

* fix #5186 by adding explicit flush.
* make test machine-independent

---------

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
GiM 2024-10-06 11:31:31 +02:00 committed by GitHub
parent bdaeac12f4
commit d8eb4e2214
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 1 deletions

View file

@ -467,6 +467,13 @@ fn write_fast<R: FdReadable>(handle: &mut InputHandle<R>) -> 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(())
}

View file

@ -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]