Orion
Barry Moving signal handlers into separate namespace 7ae31b0 (3 years, 1 month 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;
+ }
+}