In this previous question I posted most of my own shell code. My next step is to implement foreground and background process execution and properly wait for them to terminate so
There are various options to waitpid()
to help you (quotes from the POSIX standard):
WCONTINUED
The waitpid() function shall report the status of any continued child process specified by pid whose status has not been reported since it continued from a job control stop.
WNOHANG
The waitpid() function shall not suspend execution of the calling thread if status is not immediately available for one of the child processes specified by pid.
In particular, WNOHANG will allow you to see whether there are any corpses to collect without causing your process to block waiting for a corpse.
If the calling process has SA_NOCLDWAIT set or has SIGCHLD set to SIG_IGN, and the process has no unwaited-for children that were transformed into zombie processes, the calling thread shall block until all of the children of the process containing the calling thread terminate, and wait() and waitpid() shall fail and set errno to [ECHILD].
You probably don't want to be ignoring SIGCHLD, etc, and your signal handler should probably be setting a flag to tell your main loop "Oops; there's dead child - go collect that corpse!".
The SIGCONT and SIGSTOP signals will also be of relevance to you - they are used to restart and stop a child process, respectively (in this context, at any rate).
I'd recommend looking at Rochkind's book or Stevens' book - they cover these issues in detail.