mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
uucore(panic): guard against "Broken pipe" panics
Add "Broken pipe" to the set of panic messages used to determine whether a panic is caused by a broken pipe error.
This commit is contained in:
parent
5c97c1ccc4
commit
f95ab2f43c
1 changed files with 33 additions and 8 deletions
|
@ -1,17 +1,42 @@
|
|||
//! Custom panic hooks that allow silencing certain types of errors.
|
||||
//!
|
||||
//! Use the [`mute_sigpipe_panic`] function to silence panics caused by
|
||||
//! broken pipe errors. This can happen when a process is still
|
||||
//! producing data when the consuming process terminates and closes the
|
||||
//! pipe. For example,
|
||||
//!
|
||||
//! ```sh
|
||||
//! $ seq inf | head -n 1
|
||||
//! ```
|
||||
//!
|
||||
use std::panic;
|
||||
use std::panic::PanicInfo;
|
||||
|
||||
//## SIGPIPE handling background/discussions ...
|
||||
//* `uutils` ~ <https://github.com/uutils/coreutils/issues/374> , <https://github.com/uutils/coreutils/pull/1106>
|
||||
//* rust and `rg` ~ <https://github.com/rust-lang/rust/issues/62569> , <https://github.com/BurntSushi/ripgrep/issues/200> , <https://github.com/crev-dev/cargo-crev/issues/287>
|
||||
/// Decide whether a panic was caused by a broken pipe (SIGPIPE) error.
|
||||
fn is_broken_pipe(info: &PanicInfo) -> bool {
|
||||
if let Some(res) = info.payload().downcast_ref::<String>() {
|
||||
if res.contains("BrokenPipe") || res.contains("Broken pipe") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Terminate without error on panics that occur due to broken pipe errors.
|
||||
///
|
||||
/// For background discussions on `SIGPIPE` handling, see
|
||||
///
|
||||
/// * https://github.com/uutils/coreutils/issues/374
|
||||
/// * https://github.com/uutils/coreutils/pull/1106
|
||||
/// * https://github.com/rust-lang/rust/issues/62569
|
||||
/// * https://github.com/BurntSushi/ripgrep/issues/200
|
||||
/// * https://github.com/crev-dev/cargo-crev/issues/287
|
||||
///
|
||||
pub fn mute_sigpipe_panic() {
|
||||
let hook = panic::take_hook();
|
||||
panic::set_hook(Box::new(move |info| {
|
||||
if let Some(res) = info.payload().downcast_ref::<String>() {
|
||||
if res.contains("BrokenPipe") {
|
||||
return;
|
||||
}
|
||||
if !is_broken_pipe(info) {
|
||||
hook(info)
|
||||
}
|
||||
hook(info)
|
||||
}));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue