kernel+libc: Add the SA_NODEFER and SA_RESETHAND flags for sigaction()
This commit is contained in:
parent
237184a8bf
commit
86d14e0d0e
@ -5,16 +5,14 @@
|
||||
void handler(int)
|
||||
{
|
||||
puts("I caught a segfault!");
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESETHAND;
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
|
@ -120,8 +120,8 @@ bool Thread::deliver_signal(int signo, Registers* current_regs)
|
||||
if (push_mem_on_stack((u8*)&rsp, sizeof(u64)).has_error()) return false;
|
||||
if (push_mem_on_stack((u8*)&handler.__sa_sigreturn, sizeof(void*)).has_error()) return false;
|
||||
|
||||
// FIXME: Do not add the current signal to the signal mask if SA_NODEFER is set.
|
||||
signal_mask = handler.sa_mask | (1 << (signo - 1));
|
||||
signal_mask = handler.sa_mask;
|
||||
if ((handler.sa_flags & SA_NODEFER) == 0) signal_mask |= (1 << (signo - 1));
|
||||
|
||||
rsp = regs.rsp;
|
||||
|
||||
@ -132,6 +132,14 @@ bool Thread::deliver_signal(int signo, Registers* current_regs)
|
||||
|
||||
memcpy(current_regs, ®s, sizeof(regs));
|
||||
|
||||
if (handler.sa_flags & SA_RESETHAND)
|
||||
{
|
||||
handler.sa_handler = SIG_DFL;
|
||||
handler.sa_mask = 0;
|
||||
handler.sa_flags = 0;
|
||||
signal_handlers[signo - 1] = handler;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@ struct sigaction
|
||||
#endif
|
||||
};
|
||||
|
||||
// Constants for sigaction's sa_flags field.
|
||||
#define SA_NODEFER (1 << 0)
|
||||
#define SA_RESETHAND (1 << 1)
|
||||
|
||||
// Constants for the 'how' parameter in sigprocmask().
|
||||
#define SIG_BLOCK 0
|
||||
#define SIG_UNBLOCK 1
|
||||
|
Loading…
Reference in New Issue
Block a user