diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index 5f8418b3a7..375374a823 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -392,7 +392,6 @@ fn convert_old(action: &RawAction) -> Sigaction { let kind = if handler == default_handler as usize { SigactionKind::Default } else if flags.contains(SigactionFlags::IGNORED) { - // TODO: Should IGNORED always shortcut to Ignore even if handler == default_handler? SigactionKind::Ignore } else { SigactionKind::Handled { @@ -408,6 +407,18 @@ fn convert_old(action: &RawAction) -> Sigaction { } pub fn sigaction(signal: u8, new: Option<&Sigaction>, old: Option<&mut Sigaction>) -> Result<()> { + let _sigguard = tmp_disable_signals(); + let ctl = current_sigctl(); + + let _guard = SIGACTIONS_LOCK.lock(); + sigaction_inner(ctl, signal, new, old) +} +fn sigaction_inner( + ctl: &Sigcontrol, + signal: u8, + new: Option<&Sigaction>, + old: Option<&mut Sigaction>, +) -> Result<()> { // TODO: Now that the goal of keeping logic out of the IPC backend, no longer holds when // procmgr has taken over signal handling from the kernel, it would probably make sense to make // parts of this function an IPC call, for synchronization purposes. Apart from SA_RESETHAND @@ -432,11 +443,6 @@ pub fn sigaction(signal: u8, new: Option<&Sigaction>, old: Option<&mut Sigaction return Ok(()); } - let _sigguard = tmp_disable_signals(); - let ctl = current_sigctl(); - - let _guard = SIGACTIONS_LOCK.lock(); - let action = &PROC_CONTROL_STRUCT.actions[usize::from(signal) - 1]; if let Some(old) = old { @@ -904,3 +910,48 @@ fn try_claim_single(sig_idx: u32, thread_control: Option<&Sigcontrol>) -> Option }) } } +pub fn apply_inherited_sigignmask(inherited: u64) { + let _sig_guard = tmp_disable_signals(); + let _guard = SIGACTIONS_LOCK.lock(); + let ctl = current_sigctl(); + + // Set all signals in the inherited set that have explicitly been set to SIG_IGN. Those whose + // (default) effective action is to ignore but are set to SIG_DFL, are not in this set, and the + // initial SIG_DFL state would be "Ignore" anyway but still return SIG_DFL when asked, as + // usual. + for bit in (0..64).filter(|b| inherited & (1 << b) != 0) { + let sig = u8::try_from(bit + 1).unwrap(); + sigaction_inner( + ctl, + sig, + Some(&Sigaction { + // TODO: correct fields? + flags: SigactionFlags::IGNORED, + kind: SigactionKind::Ignore, + mask: 0, + }), + None, + ); + } +} +pub fn get_sigignmask_to_inherit() -> u64 { + let _sig_guard = tmp_disable_signals(); + let _guard = SIGACTIONS_LOCK.lock(); + let ctl = current_sigctl(); + + let mut mask = 0_u64; + // Fill the mask with the set of the inherited signals that have explicitly been set to + // SIG_IGN. Again this excludes signals that would have returned SIG_DFL from sigaction, + // despite their default action being "Ignore". + + for bit in 0..64 { + let sig = u8::try_from(bit + 1).unwrap(); + let mut old = Sigaction::default(); + sigaction_inner(ctl, sig, None, Some(&mut old)); + if matches!(old.kind, SigactionKind::Ignore) { + mask |= 1 << bit; + } + } + + mask +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 588c526951..f3f2789bb5 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -364,6 +364,16 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) { } } + let mut inherited_sigignmask = 0_u64; + if let Some(mask) = get_auxv(&auxvs, AT_REDOX_INHERITED_SIGIGNMASK) { + inherited_sigignmask |= mask as u64; + } + #[cfg(target_pointer_width = "32")] + if let Some(mask) = get_auxv(&auxvs, AT_REDOX_INHERITED_SIGIGNMASK_HI) { + inherited_sigignmask |= (mask as u64) << 32; + } + redox_rt::signal::apply_inherited_sigignmask(inherited_sigignmask); + let mut inherited_sigprocmask = 0_u64; if let Some(mask) = get_auxv(&auxvs, AT_REDOX_INHERITED_SIGPROCMASK) { diff --git a/src/platform/redox/exec.rs b/src/platform/redox/exec.rs index dac30ee422..7cca58d0a2 100644 --- a/src/platform/redox/exec.rs +++ b/src/platform/redox/exec.rs @@ -260,7 +260,7 @@ pub fn execve( let extrainfo = ExtraInfo { cwd: Some(&cwd), default_scheme: Some(&default_scheme), - sigignmask: 0, + sigignmask: redox_rt::signal::get_sigignmask_to_inherit(), sigprocmask, umask: redox_rt::sys::get_umask(), thr_fd: **RtTcb::current().thread_fd(),