Before going on, assume you've read my previous post on pid management
Thanks to the struct process
, our work is much simplified. Quoting Eric S.Raymond
here.
Smart data structures and dumb code works a lot better than the other way around.
sys_waitpid
At first glance, the logic of waitpid
is trivial. Yes, it's indeed in
terms of the "core code": Just acquire the exitlock and then see if the
process has exited, then wait it exit using cv_wait
on exitcv and get
it's exitcode. Here I use cv
to coordinate child and parent process. Or you can
use semaphore with initial count 0: child will V
the semaphore when it exits,
and parent will P
the semaphore on waitpid
.
But it turns out that most the code of waitpid
is argument
checking! More arguments means more potential risks from user space.
Sigh~ Anyway, we are doing kernel programming. And just take a look at
$OS161_SRC/user/testbin/badcall/bad_waitpid.c
and you'll know what I mean.
So basically, we need to check:
- Is the status pointer properly aligned (by 4) ?
- Is the status pointer a valid pointer anyway (NULL, point to kernel, ...)?
- Is options valid? (More flags than
WNOHANG | WUNTRACED
) - Does the waited pid exist/valid?
- If exist, are we allowed to wait it ? (Is it our child?)
And also, after successfully get the exitcode, don't forget to destroy the child's process structure and free its slot in the procs array. Since one child has only one parent, and after we wait for it, no one will care for it any more!
sys_exit
This part is easy. (Mostly because exit only take on integer argument!) All
we need to do is find our struct process
entry using curthread->t_pid
.
And then indicate that "I've exited" and fill the exitcode. The only
thing to note that the exitcode must be maked using the MACROs in
$OS161_SRC/kern/include/kern/wait.h
. Suppose user passing in _exitcode
, then we need
to set the real exitcode
as _MKWAIT_EXIT(_exitcode)
.
And if we are smarter, we can first check if parent exist or if parent has exited, then we even don't bother fill the exitcode since no one cares! Anyway, it's just a tiny shortcut, and totally optional.