Orion
Barry Moving signal handlers into separate namespace 7ae31b0 (2 years, 4 months ago)diff --git a/mem/pagefault.c b/mem/pagefault.c index 14219b7..4482efe 100644 --- a/mem/pagefault.c +++ b/mem/pagefault.c @@ -33,7 +33,6 @@ copy_on_write(VMRegion *region, uintptr_t addr) uint8_t private = region->flags & MAP_PRIVATE; uint8_t sharedanon = (region->flags & MAP_SHARED) && (region->flags & MAP_ANONYMOUS); - uint8_t created = 0; if (!front && (private || sharedanon)) { /* * A private mapping will always write to the front. A shared @@ -46,7 +45,6 @@ copy_on_write(VMRegion *region, uintptr_t addr) front->inode = inode_get(kmalloc(sizeof(Inode))); front->ops = &tmpfsFileOps; region->front = file_get(front); - created++; } /* Find original page frame */ diff --git a/screen.h b/screen.h index 3fbda71..d77b29f 100644 --- a/screen.h +++ b/screen.h @@ -7,7 +7,7 @@ void kprintf(char *fmt, ...); void dbgprintf(char *msg); #define ASSERT(c) ({ \ - if (!(c)) \ + if (__builtin_expect(!(c),0)) \ panic("Assertion failed (%s:%d): " #c, \ __FILE__, __LINE__); \ c; \ 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);