diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index f9c8d686bff..28c468d4f9c 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -182,6 +182,7 @@ LINESIZE NAMESIZE RTLD_NEXT RTLD +SIGABRT SIGINT SIGKILL SIGSTOP diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index 0b88e389b65..ef270546cd7 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -748,7 +748,9 @@ impl Error for ClapErrorWrapper {} // This is abuse of the Display trait impl Display for ClapErrorWrapper { fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - self.error.print().unwrap(); + // Intentionally ignore the result - error.print() writes directly to stderr + // and we always return Ok(()) to satisfy Display's contract + let _ = self.error.print(); Ok(()) } } diff --git a/tests/by-util/test_cat.rs b/tests/by-util/test_cat.rs index 33796f3ae41..2d35a2e2583 100644 --- a/tests/by-util/test_cat.rs +++ b/tests/by-util/test_cat.rs @@ -833,6 +833,37 @@ fn test_child_when_pipe_in() { ts.ucmd().pipe_in("content").run().stdout_is("content"); } +/// Regression test for GitHub issue #9769 +/// https://github.com/uutils/coreutils/issues/9769 +/// +/// Bug: Utilities panic when output is redirected to /dev/full +/// Location: src/uucore/src/lib/mods/error.rs:751 - `.unwrap()` causes panic +/// +/// This test verifies that cat handles write errors to /dev/full gracefully +/// instead of panicking with exit code 134 (SIGABRT). +/// +/// Expected behavior with current BUGGY code: +/// - Test WILL FAIL (cat panics with exit code 134) +/// +/// Expected behavior after fix: +/// - Test SHOULD PASS (cat exits gracefully with error code 1) +// Regression test for issue #9769: graceful error handling when writing to /dev/full +#[test] +#[cfg(target_os = "linux")] +fn test_write_error_handling() { + use std::fs::File; + + let dev_full = + File::create("/dev/full").expect("Failed to open /dev/full - test must run on Linux"); + + new_ucmd!() + .pipe_in("test content that should cause write error to /dev/full") + .set_stdout(dev_full) + .fails() + .code_is(1) + .stderr_contains("No space left on device"); +} + #[test] fn test_cat_eintr_handling() { // Test that cat properly handles EINTR (ErrorKind::Interrupted) during I/O operations