BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / 7ae31b03c38925f5d527e6303765925586731209 / task / signal.c

// Related

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;
+	}
+}