diff options
author | dzwdz | 2022-05-02 19:25:02 +0200 |
---|---|---|
committer | dzwdz | 2022-05-02 19:25:02 +0200 |
commit | 577ed9e01a83c13bf151b5137e6fe1eace1c4f7c (patch) | |
tree | 750dd8a3536ce70d817e6920c89042ee94899a29 /src/kernel | |
parent | d9dc6a0c4c5047c3789a16ef623eeff7c240f5a9 (diff) |
syscalls: fork() noreap flag
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/proc.c | 6 | ||||
-rw-r--r-- | src/kernel/proc.h | 3 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 10 |
3 files changed, 11 insertions, 8 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 838d520..4dfee15 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -6,6 +6,7 @@ #include <kernel/proc.h> #include <kernel/vfs/mount.h> #include <shared/mem.h> +#include <shared/syscalls.h> #include <stdint.h> struct process *process_first; @@ -49,7 +50,7 @@ struct process *process_seed(struct kmain_info *info) { return process_first; } -struct process *process_fork(struct process *parent) { +struct process *process_fork(struct process *parent, int flags) { struct process *child = kmalloc(sizeof *child); memcpy(child, parent, sizeof *child); @@ -58,6 +59,7 @@ struct process *process_fork(struct process *parent) { child->child = NULL; child->parent = parent; parent->child = child; + child->noreap = (flags & FORK_NOREAP) > 0; parent->handled_req = NULL; // TODO control this with a flag @@ -325,7 +327,7 @@ int process_try2collect(struct process *dead) { assert(dead->state == PS_DEAD); - if (!parent) { + if (!parent || dead->noreap) { process_transition(dead, PS_DEADER); return -1; } diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 26227e1..c592fd7 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -25,6 +25,7 @@ struct process { enum process_state state; bool deathbed; // kill on next process_switch attempt + bool noreap; struct process *sibling; struct process *child; @@ -64,7 +65,7 @@ extern struct process *process_current; // creates the root process struct process *process_seed(struct kmain_info *info); -struct process *process_fork(struct process *parent); +struct process *process_fork(struct process *parent, int flags); void process_forget(struct process *); // remove references to process void process_free(struct process *); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index ffacdbc..57286f1 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -21,7 +21,7 @@ int _syscall_await(void) { // find any already dead children for (struct process *iter = process_current->child; iter; iter = iter->sibling) { - if (iter->state == PS_DEAD) + if (iter->state == PS_DEAD && !iter->noreap) return process_try2collect(iter); if (iter->state != PS_DEADER) has_children = true; @@ -35,8 +35,8 @@ int _syscall_await(void) { } } -int _syscall_fork(void) { - struct process *child = process_fork(process_current); +int _syscall_fork(int flags) { + struct process *child = process_fork(process_current, flags); regs_savereturn(&child->regs, 0); return 1; } @@ -180,7 +180,7 @@ handle_t _syscall_fs_fork2(void) { backend->handler = NULL; backend->queue = NULL; - child = process_fork(process_current); + child = process_fork(process_current, 0); child->controlled = backend; regs_savereturn(&child->regs, 0); @@ -249,7 +249,7 @@ int _syscall(int num, int a, int b, int c, int d) { case _SYSCALL_AWAIT: return _syscall_await(); case _SYSCALL_FORK: - return _syscall_fork(); + return _syscall_fork(a); case _SYSCALL_OPEN: return _syscall_open((userptr_t)a, b); case _SYSCALL_MOUNT: |