43 lines
1.1 KiB
Rust
43 lines
1.1 KiB
Rust
use crate::trace;
|
|
use libsys::{
|
|
debug::TraceLevel,
|
|
calls::{sys_ex_sigreturn, sys_exit},
|
|
proc::ExitCode,
|
|
signal::Signal,
|
|
};
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub enum SignalHandler {
|
|
Func(fn(Signal) -> ()),
|
|
Ignore,
|
|
Terminate,
|
|
}
|
|
|
|
// TODO per-thread signal handler table
|
|
static mut SIGNAL_HANDLERS: [SignalHandler; 32] = [SignalHandler::Terminate; 32];
|
|
|
|
pub fn set_handler(sig: Signal, handler: SignalHandler) -> SignalHandler {
|
|
unsafe {
|
|
let old = SIGNAL_HANDLERS[sig as usize];
|
|
SIGNAL_HANDLERS[sig as usize] = handler;
|
|
old
|
|
}
|
|
}
|
|
|
|
#[inline(never)]
|
|
pub(crate) extern "C" fn signal_handler(arg: Signal) -> ! {
|
|
// TODO tpidr_el0 is invalidated when entering signal context
|
|
trace!(TraceLevel::Debug, "Entered signal handler: arg={:?}", arg);
|
|
let no = arg as usize;
|
|
if no >= 32 {
|
|
panic!("Undefined signal number: {}", no);
|
|
}
|
|
match unsafe { SIGNAL_HANDLERS[no] } {
|
|
SignalHandler::Func(f) => f(arg),
|
|
SignalHandler::Ignore => (),
|
|
SignalHandler::Terminate => sys_exit(ExitCode::from(-1)),
|
|
}
|
|
|
|
sys_ex_sigreturn();
|
|
}
|