Skip to main content

Module pipe

Module pipe 

Source
Expand description

The end of a command at a closed pipe (01M5MRG35BYRGZYD4VQVV8ZTYX).

Rust ignores SIGPIPE. A write to a pipe that its reader closed fails with EPIPE, and println! panics on that error. So riff daemon status | head -1 showed a panic after head read its line.

The usual fix sets SIGPIPE back to its default. riff does not do that: the signal would also come from a write to a socket or to the pipe of a child process. riff run reconnects when the daemon closes its socket, and the daemon and the relay serve sockets. A SIGPIPE would kill them.

end_quietly adds a panic hook in place of the signal. The panic of println! or eprintln! (also of anstream) on a closed pipe ends the process with the exit 0 and prints nothing. Each other panic goes to the hook that was there before.

flowchart LR
    P["println! at a closed pipe"] --> E[EPIPE] --> H{panic hook}
    H -- "failed printing to stdout or stderr" --> X[exit 0]
    H -- "another panic" --> D[the hook before]
    S["write to a socket"] --> Err[an error, no signal]
use riff_core::pipe::closed_pipe;

assert!(closed_pipe("failed printing to stdout: Broken pipe (os error 32)"));
assert!(!closed_pipe("failed printing to stdout: No space left on device (os error 28)"));

Functionsยง

closed_pipe
True when message is the panic of a print to stdout or stderr that failed because the reader closed the pipe. println!, eprintln! and the macros of anstream panic with this message.
end_quietly
Adds the panic hook: a print to a closed pipe ends the process with the exit 0, and prints nothing. Call it at the start of main of a command that ends by itself, never of a server: the hook ends the whole process from each thread.