coreutils
coreutils copied to clipboard
Panic in multiple programs when redirecting stdout to /dev/full
uutils programs panic when attempting to redirect stdout to /dev/full with a "could not flush stdout" error.
For example, GNU seq:
$ seq inf > /dev/full
seq: write error: No space left on device
uutils seq:
$ ./target/debug/seq inf > /dev/full
./target/debug/seq: write error: No space left on device
thread 'main' panicked at 'could not flush stdout: Os { code: 28, kind: StorageFull, message: "No space left on device" }', src/uu/seq/src/main.rs:1:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Similar results can be seen for other programs as well; I tried echo and printf.
This is gonna be quite a challenge, because even the most barebones hello world app fails this test:
❯ bat src/main.rs
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: src/main.rs
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ fn main() {
2 │ println!("Hello, world!");
3 │ }
───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯ cargo run > /dev/full
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/claptest`
thread 'main' panicked at 'failed printing to stdout: No space left on device (os error 28)', library/std/src/io/stdio.rs:1201:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
So, I think we have a couple of options:
- Provide custom
print!/println!macros, which is not a great option as they will probably be inferior to or go out of sync with the original macros. - Disallow
print!/println!and only usewrite!/writeln!with proper error handling, which increases the maintenance burden a lot. - Set
panic = "abort"in Cargo.toml, which is also not great because we still need to print the error to stderr. - Use something like
catch_unwindin themain!orgen_uumainmacros to catch the panic and print the error message.
Are there any options I'm missing?
Both panic = "abort" and catch_unwind will still show panic messages when the panic happens. panic = "abort" causes it to abort instead of attempt to unwind after a panic. catch_unwind allows you to stop the unwinding and resume execution. For uutils panic = "abort" makes sense I think as panics won't be recovered from anyway and I would expect there aren't any drop implementations that need to run even when panicking.
This is causing an error in GNU test suite file tests/misc/csplit-io-error.sh. (There is a seq 1 > /dev/full command in that file.)