Skip to content

Commit 54e0bea

Browse files
Handle SIGPIPE
Fix `SIGPIPE` being ignored, which would cause the `mullvad-cli` to panic if it received a `PIPE` signal (e.g. it was piped into `echo`).
1 parent 6192767 commit 54e0bea

File tree

4 files changed

+22
-0
lines changed

4 files changed

+22
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Line wrap the file at 100 chars. Th
3232
- Remove "Any" option for tunnel protocol. The default is now WireGuard.
3333

3434
### Fixed
35+
- Fix `mullvad-cli` panicking if it tried to write to a closed pipe on Linux and macOS.
36+
3537
#### macOS
3638
- Fix routing issue caused by upgrading `tun`.
3739

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mullvad-cli/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ serde_json = { workspace = true }
3434

3535
[target.'cfg(all(unix, not(target_os = "android")))'.dependencies]
3636
clap_complete = { version = "4.4.8" }
37+
nix = { version = "0.29.0", features = ["signal"] }
3738

3839
[target.'cfg(windows)'.build-dependencies]
3940
winres = "0.1"

mullvad-cli/src/main.rs

+18
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ enum Cli {
152152

153153
#[tokio::main]
154154
async fn main() -> Result<()> {
155+
// Handle SIGPIPE
156+
// https://stackoverflow.com/questions/65755853/simple-word-count-rust-program-outputs-valid-stdout-but-panicks-when-piped-to-he/65760807
157+
// https://github.com/typst/typst/pull/5444
158+
#[cfg(unix)]
159+
handle_sigpipe().unwrap();
160+
155161
match Cli::parse() {
156162
Cli::Account(cmd) => cmd.handle().await,
157163
Cli::Bridge(cmd) => cmd.handle().await,
@@ -189,3 +195,15 @@ async fn main() -> Result<()> {
189195
}
190196
}
191197
}
198+
199+
/// Install the default signal handler for `SIGPIPE`.
200+
///
201+
/// By default, Rust replaces it with an empty handler because reasons: https://github.com/rust-lang/rust/issues/119980
202+
#[cfg(unix)]
203+
fn handle_sigpipe() -> Result<(), nix::errno::Errno> {
204+
use nix::sys::signal::{signal, SigHandler, Signal};
205+
// SAFETY: We do not use the previous signal handler, which could cause UB if done carelessly:
206+
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html
207+
unsafe { signal(Signal::SIGPIPE, SigHandler::SigDfl) }?;
208+
Ok(())
209+
}

0 commit comments

Comments
 (0)