coreutils icon indicating copy to clipboard operation
coreutils copied to clipboard

Panic in multiple programs when redirecting stdout to /dev/full

Open jfinkels opened this issue 3 years ago • 3 comments
trafficstars

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.

jfinkels avatar Jan 27 '22 03:01 jfinkels

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 use write!/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_unwind in the main! or gen_uumain macros to catch the panic and print the error message.

Are there any options I'm missing?

tertsdiepraam avatar Jan 27 '22 10:01 tertsdiepraam

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.

bjorn3 avatar Jan 29 '22 14:01 bjorn3

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.)

jfinkels avatar Apr 09 '22 21:04 jfinkels