Orion
Barry Moving signal handlers into separate namespace 7ae31b0 (2 years, 4 months ago)diff --git a/task/signal.c b/task/signal.c index c80c279..fce04de 100644 --- a/task/signal.c +++ b/task/signal.c @@ -26,18 +26,25 @@ handle_signals(void) } } +/* Send a signal to a task */ +void +send_sig(Task *target, int sig) +{ + target->sigset |= (1 << (sig - 1)); +} + /* Send a signal to a thread */ int tgkill(pid_t tgid, pid_t tid, int sig) { - if (sig < 0 || sig > 31) + if (sig < 0 || sig >= 32) return -EINVAL; Task *task = find_task(tid); if (!task || task->tgid != tgid) return -ESRCH; if (sig) - task->sigset |= (1 << (sig - 1)); + send_sig(task, sig); return 0; } @@ -46,7 +53,7 @@ tgkill(pid_t tgid, pid_t tid, int sig) int kill(pid_t pid, int sig) { - if (sig < 0 || sig > 31) + if (sig < 0 || sig >= 32) return -EINVAL; int sent = 0; @@ -55,9 +62,54 @@ kill(pid_t pid, int sig) if (task->tgid != pid) continue; if (sig) - task->sigset |= (1 << (sig - 1)); + send_sig(task, sig); sent++; } return sent ? 0 : -ESRCH; } + +/* Install a signal handler */ +sighandler_t +signal(int signum, sighandler_t handler) +{ + if (signum < 0 || signum >= 32) + return (sighandler_t) -EINVAL; + + if (!verify_access(handler, 8, PROT_EXEC)) + return (sighandler_t) -EFAULT; + + sighandler_t old = current->signals->sig_handler[signum]; + current->signals->sig_handler[signum] = handler; + return old; +} + +/* Examine and change blocked signals */ +int +sigprocmask(int how, const sigset_t *set, sigset_t *oldset) +{ + if (!verify_access(set, sizeof(sigset_t), PROT_READ)) + return -EFAULT; + if (!verify_access(oldset, sizeof(sigset_t), PROT_WRITE)) + return -EFAULT; + + if (oldset) + *oldset = current->blockedSignals; + + if (!set) + return 0; + + switch (how) { + case SIG_BLOCK: + current->blockedSignals |= *set; + return 0; + case SIG_UNBLOCK: + current->blockedSignals &= ~*set; + return 0; + case SIG_SETMASK: + current->blockedSignals = *set; + return 0; + default: + return -EINVAL; + } +}