wc: stop processing --files0-from input after stdout write failure (#11023)

* fix(wc): stop processing after stdout write error

When wc encounters a write error to stdout (e.g., when stdout is redirected to /dev/full), it should stop processing immediately rather than continuing to process remaining files. This matches GNU wc behavior and prevents unnecessary processing after the output is already broken.

* fix(wc): improve error message matching in test_files0_stops_after_stdout_write_error
This commit is contained in:
mattsu
2026-02-19 17:33:42 +09:00
committed by GitHub
parent 84165bedd2
commit 2b10153e21
2 changed files with 25 additions and 0 deletions
+1
View File
@@ -988,6 +988,7 @@ fn wc(inputs: &Inputs, settings: &Settings) -> UResult<()> {
if let Err(err) = print_stats(settings, &word_count, maybe_title_str, number_width) {
let title = maybe_title_str.unwrap_or(OsStr::new("<stdin>"));
show!(err.map_err_context(|| translate!("wc-error-failed-to-print-result", "title" => title.to_string_lossy())));
return Ok(());
}
}
// Print deferred error after stats to match GNU wc output order
+24
View File
@@ -763,6 +763,30 @@ fn test_files0_progressive_stream() {
.stdout_only("36 370 2189 total\n");
}
#[cfg(target_os = "linux")]
#[test]
fn test_files0_stops_after_stdout_write_error() {
use std::fs::OpenOptions;
let dev_full = OpenOptions::new().write(true).open("/dev/full").unwrap();
let stderr = new_ucmd!()
.args(&["--files0-from=-", "--total=never"])
.set_stdout(dev_full)
.pipe_in(b"/dev/null\0/dev/null\0/dev/null\0")
.fails()
.stderr_str()
.to_string();
assert_eq!(
stderr
.matches("failed to print result for /dev/null")
.count(),
1,
"wc should stop after the first stdout write error: {stderr:?}"
);
}
#[test]
fn files0_from_dir() {
// On Unix, `read(open("."))` fails. On Windows, `open(".")` fails. Thus, the errors happen in