summaryrefslogtreecommitdiff
path: root/src/kernel/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/syscalls.c')
-rw-r--r--src/kernel/syscalls.c33
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: