diff options
Diffstat (limited to 'kernel/proc/proc.c')
-rw-r--r-- | kernel/proc/proc.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 6155b58..fd253f6 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -340,7 +340,7 @@ void proc_kill_all() } } - // kill the current proc + // kill this proc do_exit(0); } @@ -416,7 +416,58 @@ void proc_destroy(proc_t *proc) */ pid_t do_waitpid(pid_t pid, int *status, int options) { - NOT_YET_IMPLEMENTED("PROCS: do_waitpid"); + // NOT_YET_IMPLEMENTED("PROCS: do_waitpid"); + + if (pid == 0 || options != 0 || pid < -1) + { + return -ENOTSUP; + } + + if (pid > 0) + { + proc_t *child = proc_lookup(pid); + if (child == NULL || child->p_pproc != curproc) + { + return -ECHILD; + } + + // sleep until this specific child process exits + while (child->p_state != PROC_DEAD) + { + sched_sleep_on(&curproc->p_wait); + } + + if (status != NULL) + { + *status = child->p_status; + } + proc_destroy(child); + + return pid; + } + else if (pid == -1) + { + if (list_empty(&curproc->p_children)) + { + return -ECHILD; + } + + proc_t *child; + list_iterate(&curproc->p_children, child, proc_t, p_child_link) + { + if (child->p_state == PROC_DEAD) + { + if (status != NULL) + { + *status = child->p_status; + } + + proc_destroy(child); + return child->p_pid; + } + } + } + return 0; } @@ -425,7 +476,9 @@ pid_t do_waitpid(pid_t pid, int *status, int options) */ void do_exit(long status) { - NOT_YET_IMPLEMENTED("PROCS: do_exit"); + // NOT_YET_IMPLEMENTED("PROCS: do_exit"); + + kthread_exit((void *)status); } /*========== |