aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/mod.rs8
-rw-r--r--src/platform/unix_common.rs19
2 files changed, 27 insertions, 0 deletions
diff --git a/src/platform/mod.rs b/src/platform/mod.rs
index e3f9c7f4..a63b7565 100644
--- a/src/platform/mod.rs
+++ b/src/platform/mod.rs
@@ -198,6 +198,14 @@ pub(crate) struct RemoteSshConfigPaths {
#[cfg(unix)]
mod unix_common;
+#[cfg(unix)]
+pub(crate) use unix_common::{begin_cli_output, end_cli_output};
+
+#[cfg(not(unix))]
+pub(crate) fn begin_cli_output() {}
+
+#[cfg(not(unix))]
+pub(crate) fn end_cli_output() {}
#[cfg(target_os = "linux")]
mod linux;
diff --git a/src/platform/unix_common.rs b/src/platform/unix_common.rs
index fa7b6d20..b997049f 100644
--- a/src/platform/unix_common.rs
+++ b/src/platform/unix_common.rs
@@ -1,5 +1,24 @@
use std::path::{Path, PathBuf};
+fn set_sigpipe_disposition(handler: libc::sighandler_t) {
+ let mut action: libc::sigaction = unsafe { std::mem::zeroed() };
+ action.sa_sigaction = handler;
+ unsafe {
+ libc::sigemptyset(&mut action.sa_mask);
+ // Rust starts with SIGPIPE ignored. If this best-effort transition
+ // fails, stdout retains the existing Rust behavior.
+ libc::sigaction(libc::SIGPIPE, &action, std::ptr::null_mut());
+ }
+}
+
+pub(crate) fn begin_cli_output() {
+ set_sigpipe_disposition(libc::SIG_DFL);
+}
+
+pub(crate) fn end_cli_output() {
+ set_sigpipe_disposition(libc::SIG_IGN);
+}
+
pub(crate) fn remote_ssh_config_paths() -> super::RemoteSshConfigPaths {
super::RemoteSshConfigPaths {
user_config: std::env::var_os("HOME")