Feat: POSIX signal
This commit is contained in:
59
kernel/lib/signal.c
Normal file
59
kernel/lib/signal.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <signal.h>
|
||||
#include <logger.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <thread.h>
|
||||
#include <kmalloc.h>
|
||||
#include <interrupt.h>
|
||||
#include <exec.h>
|
||||
|
||||
static inline
|
||||
void _sighandler_wrapper(signal_handler_t handler)
|
||||
{
|
||||
handler();
|
||||
asm volatile(
|
||||
"mov x8, #10" ENDL
|
||||
"svc 0"
|
||||
::: "x8"
|
||||
);
|
||||
}
|
||||
|
||||
static inline
|
||||
void _sigkill_default_handler()
|
||||
{
|
||||
thread_t *th = get_current();
|
||||
th->status = THREAD_STATUS_ZOMBIE;
|
||||
}
|
||||
|
||||
void run_signal(int32_t SIGNAL)
|
||||
{
|
||||
LOG("run_signal"); DEBUG_SIGNAL(SIGNAL);
|
||||
process_t *process = get_current()->process;
|
||||
process->current_signal = SIGNAL;
|
||||
trapframe_t *regs = kmalloc(sizeof(trapframe_t));
|
||||
memcpy(regs, process->regs, sizeof(trapframe_t));
|
||||
|
||||
if (!process->sighandlers[SIGNAL]) {
|
||||
switch (SIGNAL) {
|
||||
case SIGKILL:
|
||||
_sigkill_default_handler();
|
||||
break;
|
||||
default:
|
||||
LOG("No default handler for this signal"); DEBUG_SIGNAL(SIGNAL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*regs = (trapframe_t){
|
||||
.x0 = (uint64_t)process->sighandlers[SIGNAL],
|
||||
.elr_el1 = (uint64_t)_sighandler_wrapper,
|
||||
.sp_el0 = ((uint64_t)process->sigstack + process->sigstack_size - 64),
|
||||
};
|
||||
|
||||
disable_interrupt();
|
||||
process->current_signal = 0x0;
|
||||
process->sigstate[SIGNAL] = false;
|
||||
user_exec(regs);
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
Reference in New Issue
Block a user