waitpid - wait for a process to exit
Standard C Library (libc, -lc)
#include <sys/wait.h>
pid_t
waitpid(pid_t pid, int *status,
int options);
Wait for the process specified by pid to exit, and return an encoded exit status in the integer pointed to by status. If that process has exited already, waitpid returns immediately. If that process does not exist, waitpid fails.
It is explicitly allowed for status to be NULL, in which case waitpid operates normally but the status value is not produced.
A process moves from "has exited already" to "does not exist" when every process that is expected to collect its exit status with waitpid has done so.
In the standard Unix model of processes, the only process that is expected to collect another process's exit status is its parent. (If you feel this is restrictive, you might try to extend the model or define a new one; however, this is not recommended. The only other model that really makes much sense is to let any process wait for any other process; but then you need to check for and reject combinations that would cause deadlock.)
There are several semi-standard and messy/ugly ways in Unix for a process to indicate that it doesn't want to collect the exit status of a child it forks and therefore shouldn't be expected to. You do not need to implement any of these, but you might find it convenient for your own purposes to provide this functionality.
If a parent process exits before one or more of its children, it can no longer be expected collect their exit status. There are several ways to handle this case in practice, of which the traditional Unix method is only one. This is something you should design.
The options argument should be 0. You are not required to implement any options. (However, your system should check to make sure that requests for options you do not support are rejected.)
If you desire, you may implement the Unix option WNOHANG; this causes waitpid, when called for a process that has not yet exited, to return 0 immediately instead of waiting.
The Unix option WUNTRACED, to ask for reporting of processes that stop as well as exit, is also defined in the header files, but implementing this feature is not required or necessary unless you are implementing job control.
You may also make up your own options if you find them helpful. However, please, document anything you make up.
The encoding of the exit status is comparable to Unix and is defined by the flags found in <kern/wait.h>. (Userlevel code should include <sys/wait.h> to get these definitions.) A process can exit by calling _exit() or it can exit by receiving a fatal signal. In the former case the _MKWAIT_EXIT() macro should be used with the user-supplied exit code value to prepare the exit status; in the latter, the _MKWAIT_SIG() macro (or _MKWAIT_CORE() if a core file was generated) should be used with the signal number. The result encoding also allows notification of processes that have stopped; this would be used in connection with job control and with ptrace-based debugging if you were to implement those things.
The _MKWAIT flags are not standard and should be considered part of the implementation.
To read the wait status, use the macros WIFEXITED(), WIFSIGNALED(), and/or WIFSTOPPED() to find out what happened, and then WEXITSTATUS(), WTERMSIG(), or WSTOPSIG() respectively to get the exit code or signal number. If WIFSIGNALED() is true, WCOREDUMP() can be used to check if a core file was generated. This is the same as Unix, although the value encoding is different from the historic Unix format.
waitpid returns the process id whose exit status is reported in status. In OS/161, this is always the value of pid.
(In Unix, but not by default OS/161, you can wait for any of several processes by passing magic values of pid, so this return value can actually be useful.)
If you implement WNOHANG, and WNOHANG is given, and the process specified by pid has not yet exited, waitpid returns 0.
On error, -1 is returned, and errno is set to a suitable error code for the error condition encountered.
The following error codes should be returned under the conditions given. Other error codes may be returned for other cases not mentioned here.
EINVAL | The options argument requested invalid or unsupported options. | |
ECHILD | The pid argument named a process that was not a child of the current process. | |
ESRCH | The pid argument named a nonexistent process. | |
EFAULT | The status argument was an invalid pointer. |