From ab0366a07626806cf3b27a857148bd33a0a42c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 29 Mar 2020 14:12:18 +0200 Subject: [PATCH] Add method to `sc-cli` to reset the `SIGPIPE` signal handler (#5447) The signal handler will be reset to the default system one. This means the program will be exited instead of panicking. This is required to support piping in the console. --- substrate/Cargo.lock | 1 + substrate/bin/node/cli/src/command.rs | 2 ++ substrate/client/cli/Cargo.toml | 3 +++ substrate/client/cli/src/lib.rs | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index b0d6c55686..e87be8f0fb 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -5832,6 +5832,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", + "nix", "parity-util-mem", "regex", "rpassword", diff --git a/substrate/bin/node/cli/src/command.rs b/substrate/bin/node/cli/src/command.rs index 21584f0898..6e9b5ca575 100644 --- a/substrate/bin/node/cli/src/command.rs +++ b/substrate/bin/node/cli/src/command.rs @@ -25,6 +25,8 @@ where I: Iterator, T: Into + Clone, { + sc_cli::reset_signal_pipe_handler()?; + let args: Vec<_> = args.collect(); let opt = sc_cli::from_iter::(args.clone(), &version); diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index d623d670ad..7b9313c8d6 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -44,6 +44,9 @@ parity-util-mem = { version = "0.6.0", default-features = false, features = ["pr [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" +[target.'cfg(target_family = "unix")'.dependencies] +nix = "0.17.0" + [dev-dependencies] tempfile = "3.1.0" diff --git a/substrate/client/cli/src/lib.rs b/substrate/client/cli/src/lib.rs index f94df935a1..18a5991e39 100644 --- a/substrate/client/cli/src/lib.rs +++ b/substrate/client/cli/src/lib.rs @@ -221,3 +221,21 @@ fn kill_color(s: &str) -> String { } RE.replace_all(s, "").to_string() } + +/// Reset the signal pipe (`SIGPIPE`) handler to the default one provided by the system. +/// This will end the program on `SIGPIPE` instead of panicking. +/// +/// This should be called before calling any cli method or printing any output. +pub fn reset_signal_pipe_handler() -> Result<()> { + #[cfg(target_family = "unix")] + { + use nix::sys::signal; + + unsafe { + signal::signal(signal::Signal::SIGPIPE, signal::SigHandler::SigDfl) + .map_err(|e| Error::Other(e.to_string()))?; + } + } + + Ok(()) +}