diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index 9b4db9b60..3c7ccdc23 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -146,6 +146,9 @@ namespace Kernel case SYS_KILL: ret = Process::current().sys_kill((pid_t)arg1, (int)arg2, interrupt_stack.rsp, interrupt_stack.rip); break; + case SYS_SIGNAL: + ret = Process::current().sys_signal((int)arg1, (void (*)(int))arg2); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index 3ce74f298..ddba8e892 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -43,6 +43,7 @@ __BEGIN_DECLS #define SYS_DUP2 36 #define SYS_RAISE 37 #define SYS_KILL 38 +#define SYS_SIGNAL 39 __END_DECLS diff --git a/libc/signal.cpp b/libc/signal.cpp index 93ce5e728..39f869436 100644 --- a/libc/signal.cpp +++ b/libc/signal.cpp @@ -10,4 +10,10 @@ int raise(int sig) int kill(pid_t pid, int sig) { return syscall(SYS_KILL, pid, sig); +} + +void (*signal(int sig, void (*func)(int)))(int) +{ + long ret = syscall(SYS_SIGNAL, sig, func); + return (void (*)(int))ret; } \ No newline at end of file diff --git a/libc/unistd.cpp b/libc/unistd.cpp index f4c2e8c1a..2b9b7eed8 100644 --- a/libc/unistd.cpp +++ b/libc/unistd.cpp @@ -279,6 +279,13 @@ long syscall(long syscall, ...) ret = Kernel::syscall(SYS_KILL, pid, signal); break; } + case SYS_SIGNAL: + { + int signal = va_arg(args, int); + void (*handler)(int) = va_arg(args, void(*)(int)); + ret = Kernel::syscall(SYS_SIGNAL, signal, (uintptr_t)handler); + break; + } default: puts("LibC: Unhandeled syscall"); ret = -ENOSYS;