in sgx_signal/src/signal.rs [147:207]
fn native_sigaction_impl<F>(
signo: SigNum,
act: &sigaction,
oldact: &mut sigaction,
f: Arc<F>,
) -> SysResult<ActionId>
where
F: Fn(&siginfo_t) + Sync + Send + 'static,
{
let global = GlobalData::ensure();
let mut mask = SigSet::new();
let old_mask = SigSet::new();
mask.fill();
// Guards sigaction calls. This is to ensure that signal handlers are not
// overwritten between the time sigaction gets |oldact| and sets |act|.
let (exist, action_id) = {
let _guard = global.signal_action_lock.lock();
let exist = if let Some(t) = global.signal_manager.get_action(signo) {
*oldact = t.get_act();
true
} else {
oldact.sa_sigaction = SIG_DFL;
false
};
rsgx_sigprocmask(SIG_SETMASK, &mask.raw(), &mut old_mask.raw());
let action_id = global.signal_manager.set_action_impl(signo, act, f);
rsgx_sigprocmask(SIG_SETMASK, &old_mask.raw(), &mut mask.raw());
(exist, action_id)
};
if exist {
return Ok(action_id);
}
let new_act = sigaction {
sa_sigaction: 0,
sa_mask: act.sa_mask,
sa_flags: act.sa_flags,
sa_restorer: None,
};
if (new_act.sa_flags & SA_RESETHAND) != 0 {
global.signal_manager.set_reset_on_handle(signo);
}
let result = unsafe {
sigaction(
signo.raw(),
&new_act,
oldact as *mut sigaction,
get_enclave_id(),
)
};
if result == 0 {
Ok(action_id)
} else {
Err(result)
}
}