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.
This commit is contained in:
parent
542febd2d3
commit
a52c79e859
8 changed files with 136 additions and 72 deletions
|
@ -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() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue