BarryServer : Git

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

// Related

Orion

Barry Moving signal handlers into separate namespace 7ae31b0 (2 years, 4 months ago)
diff --git a/task/schedule.c b/task/schedule.c
index 1c00576..527b9ec 100644
--- a/task/schedule.c
+++ b/task/schedule.c
@@ -103,6 +103,8 @@ Task *
 pop_from_queue(TaskQueue *queue)
 {
 	Task *head = queue->start;
+	if (!head)
+		return NULL;
 	queue->start = head->next;
 	if (!queue->start)
 		queue->end = NULL;
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;
+	}
+}
diff --git a/task/syscall.c b/task/syscall.c
index d43542d..30e1a7b 100644
--- a/task/syscall.c
+++ b/task/syscall.c
@@ -14,25 +14,27 @@
 /* List of syscalls */
 void *syscalls[] = {
 	/* Tasking */
-	[SYSCALL_DBGPRINTF] = dbgprintf,
-	[SYSCALL_CLONE]     = clone,
-	[SYSCALL_EXIT]      = exit,
-	[SYSCALL_GETPID]    = getpid,
-	[SYSCALL_GETUID]    = getuid,
-	[SYSCALL_SETUID]    = setuid,
-	[SYSCALL_GETEUID]   = geteuid,
-	[SYSCALL_SETEUID]   = seteuid,
-	[SYSCALL_GETGID]    = getgid,
-	[SYSCALL_SETGID]    = setgid,
-	[SYSCALL_GETEGID]   = getegid,
-	[SYSCALL_SETEGID]   = setegid,
-	[SYSCALL_EXECVE]    = execve,
-	[SYSCALL_WAITPID]   = waitpid,
-	[SYSCALL_TGKILL]    = tgkill,
-	[SYSCALL_KILL]      = kill,
-	[SYSCALL_TIME]      = time,
-	[SYSCALL_TIMES]     = times,
-	[SYSCALL_SLEEP]     = sleep,
+	[SYSCALL_DBGPRINTF]   = dbgprintf,
+	[SYSCALL_CLONE]       = clone,
+	[SYSCALL_EXIT]        = exit,
+	[SYSCALL_GETPID]      = getpid,
+	[SYSCALL_GETUID]      = getuid,
+	[SYSCALL_SETUID]      = setuid,
+	[SYSCALL_GETEUID]     = geteuid,
+	[SYSCALL_SETEUID]     = seteuid,
+	[SYSCALL_GETGID]      = getgid,
+	[SYSCALL_SETGID]      = setgid,
+	[SYSCALL_GETEGID]     = getegid,
+	[SYSCALL_SETEGID]     = setegid,
+	[SYSCALL_EXECVE]      = execve,
+	[SYSCALL_WAITPID]     = waitpid,
+	[SYSCALL_TGKILL]      = tgkill,
+	[SYSCALL_KILL]        = kill,
+	[SYSCALL_SIGNAL]      = signal,
+	[SYSCALL_SIGPROCMASK] = sigprocmask,
+	[SYSCALL_TIME]        = time,
+	[SYSCALL_TIMES]       = times,
+	[SYSCALL_SLEEP]       = sleep,
 
 	/* Files */
 	[SYSCALL_OPEN]     = open,
diff --git a/task/task.c b/task/task.c
index 294b3cc..4657c4f 100644
--- a/task/task.c
+++ b/task/task.c
@@ -189,6 +189,15 @@ clone(int flags)
 			child->tls->back = file_get(parent->tls->back);
 	}
 
+	/* Signal handlers */
+	if (flags & CLONE_SIGHAND) {
+		child->signals = parent->signals;
+		child->signals->usage++;
+	} else {
+		child->signals = kmalloc(sizeof(SigHandlers));
+		child->signals->usage = 1;
+	}
+
 	/* Split tasks here */
 	uintptr_t esp, ebp, eip;
 	eip = read_eip();
@@ -232,10 +241,11 @@ terminate(void)
 	}
 	vm_destroy_region(current->stack);
 
-	/* Clean unread IPC messages */
-	/* TODO */
-
 	/* Clean signals */
+	if (--current->signals->usage == 0)
+		kfree(current->signals);
+
+	/* Clean unread IPC messages */
 	/* TODO */
 
 	/* Deschedule */
@@ -412,9 +422,11 @@ init_tasking(void)
 	current->vm->regions = NULL;
 	current->vm->usage = 1;
 
-	/* Inter-Process Communication Namespace */
-
 	/* Signals Namespace */
+	current->signals = kmalloc(sizeof(SigHandlers));
+	current->signals->usage = 1;
+
+	/* Inter-Process Communication Namespace */
 
 	register_interrupt(0, timer_handler);
 }
diff --git a/task/task.h b/task/task.h
index 228c3d8..4879c33 100644
--- a/task/task.h
+++ b/task/task.h
@@ -6,6 +6,7 @@
 #include <sys/times.h>
 #include <time.h>
 #include <signal.h>
+#include "signal.h"
 #include "../mem/paging.h"
 #include "../mem/vm.h"
 #include "../proc/proc.h"
@@ -31,7 +32,7 @@ enum States {
 	READY,
 	TERMINATED,
 	WAITING_FOR_CHILD,
-	WAITING_FOR_READ,
+	WAITING_FOR_IO,
 	SLEEP,
 };
 
@@ -63,7 +64,6 @@ struct Task {
 	TaskQueue waiting;
 	sigset_t sigset;
 	sigset_t blockedSignals;
-	void (*sig_handler[32])(int);
 
 	/* Messages */
 	Message *msgQueue;
@@ -72,8 +72,8 @@ struct Task {
 	FileSystem *fs;
 	Files *files;
 	VirtualMemory *vm;
+	SigHandlers *signals;
 //	Messages *ipc;
-//	Signals *signals;
 };
 
 extern Task *currentTask[];
@@ -122,6 +122,7 @@ int setegid(gid_t egid);
 int isatty(int fd);
 int execve(const char *file, char *argv[], char *envp[]);
 
+void send_sig(Task *target, int sig);
 int tgkill(pid_t tgid, pid_t tid, int sig);
 int kill(pid_t pid, int sig);