diff options
Diffstat (limited to 'src/kernel/syscalls.c')
-rw-r--r-- | src/kernel/syscalls.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 6a61a9d..060b983 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -8,6 +8,14 @@ _Noreturn void _syscall_exit(const char *msg, size_t len) { process_current->state = PS_DEAD; + // check if our parent is awaiting our death + if (process_current->parent->state == PS_WAITS4CHILDDEATH) { + // how cruel + process_current->state = PS_DEADER; + process_current->parent->state = PS_RUNNING; + process_switch(process_current->parent); + } + process_current = process_find(PS_RUNNING); if (process_current) process_switch(process_current); @@ -16,6 +24,29 @@ _Noreturn void _syscall_exit(const char *msg, size_t len) { panic(); } +int _syscall_await(char *buf, int *len) { + // find any already dead children + for (struct process *iter = process_current->child; + iter; iter = iter->sibling) { + if (iter->state == PS_DEAD) { + iter->state = PS_DEADER; + // TODO copy return message + return 0; + } + } + + // no dead children yet + // TODO check if the process even has children + + process_current->state = PS_WAITS4CHILDDEATH; + process_current = process_find(PS_RUNNING); + if (process_current) + process_switch(process_current); + + tty_const("this error will be fixed in the next commit."); // TODO + panic(); +} + int _syscall_fork() { struct process *child = process_fork(process_current); regs_savereturn(&child->regs, 0); @@ -38,6 +69,8 @@ int syscall_handler(int num, int a, int b, int c) { switch (num) { case _SYSCALL_EXIT: _syscall_exit((void*)a, b); + case _SYSCALL_AWAIT: + return _syscall_await((void*)a, (void*)b); case _SYSCALL_FORK: return _syscall_fork(); case _SYSCALL_DEBUGLOG: |