about summary refs log tree commit diff
path: root/library/std/src/sys/unix/mod.rs
diff options
context:
space:
mode:
authorRain <rain@sunshowers.io>2022-09-22 22:48:14 -0700
committerRain <rain@sunshowers.io>2022-10-20 14:53:38 -0700
commita52c79e859142c1cd5c0c5bdb73f16b754e1b98f (patch)
treeac8aea871f084c1521a9ee86c6adc3cf19313967 /library/std/src/sys/unix/mod.rs
parent542febd2d383b5082277c7d165b098c0a3b513f6 (diff)
downloadrust-a52c79e859142c1cd5c0c5bdb73f16b754e1b98f.tar.gz
rust-a52c79e859142c1cd5c0c5bdb73f16b754e1b98f.zip
Change process spawning to inherit the parent's signal mask by default
Previously, the signal mask is always reset when a child process is
started. This breaks tools like `nohup` which expect `SIGHUP` to be
blocked.

With this change, the default behavior changes to inherit the signal mask.

This also changes the signal disposition for `SIGPIPE` to only be
changed if the `#[unix_sigpipe]` attribute isn't set.
Diffstat (limited to 'library/std/src/sys/unix/mod.rs')
-rw-r--r--library/std/src/sys/unix/mod.rs38
1 files changed, 34 insertions, 4 deletions
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index c84e292eac1..4a9f356b63c 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -163,17 +163,27 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             // See the other file for docs. NOTE: Make sure to keep them in
             // sync!
             mod sigpipe {
+                pub const DEFAULT: u8 = 0;
                 pub const INHERIT: u8 = 1;
                 pub const SIG_IGN: u8 = 2;
                 pub const SIG_DFL: u8 = 3;
             }
 
-            let handler = match sigpipe {
-                sigpipe::INHERIT => None,
-                sigpipe::SIG_IGN => Some(libc::SIG_IGN),
-                sigpipe::SIG_DFL => Some(libc::SIG_DFL),
+            let (sigpipe_attr_specified, handler) = match sigpipe {
+                sigpipe::DEFAULT => (false, Some(libc::SIG_IGN)),
+                sigpipe::INHERIT => (true, None),
+                sigpipe::SIG_IGN => (true, Some(libc::SIG_IGN)),
+                sigpipe::SIG_DFL => (true, Some(libc::SIG_DFL)),
                 _ => unreachable!(),
             };
+            // The bootstrap compiler doesn't know about sigpipe::DEFAULT, and always passes in
+            // SIG_IGN. This causes some tests to fail because they expect SIGPIPE to be reset to
+            // default on process spawning (which doesn't happen if #[unix_sigpipe] is specified).
+            // Since we can't differentiate between the cases here, treat SIG_IGN as DEFAULT
+            // unconditionally.
+            if sigpipe_attr_specified && !(cfg!(bootstrap) && sigpipe == sigpipe::SIG_IGN) {
+                UNIX_SIGPIPE_ATTR_SPECIFIED.store(true, crate::sync::atomic::Ordering::Relaxed);
+            }
             if let Some(handler) = handler {
                 rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
             }
@@ -181,6 +191,26 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     }
 }
 
+// This is set (up to once) in reset_sigpipe.
+#[cfg(not(any(
+    target_os = "espidf",
+    target_os = "emscripten",
+    target_os = "fuchsia",
+    target_os = "horizon"
+)))]
+static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
+    crate::sync::atomic::AtomicBool::new(false);
+
+#[cfg(not(any(
+    target_os = "espidf",
+    target_os = "emscripten",
+    target_os = "fuchsia",
+    target_os = "horizon"
+)))]
+pub(crate) fn unix_sigpipe_attr_specified() -> bool {
+    UNIX_SIGPIPE_ATTR_SPECIFIED.load(crate::sync::atomic::Ordering::Relaxed)
+}
+
 // SAFETY: must be called only once during runtime cleanup.
 // NOTE: this is not guaranteed to run, for example when the program aborts.
 pub unsafe fn cleanup() {