Monitoring Child processes
If the calling process has no children, then waitpid returns −1 and sets errno to
ECHILD
. If the waitpid function was interrupted by a signal, then it returns −1
and sets errno to EINTR
The wait() system call
- The
wait()
system call waits for one of the children of the calling process to terminate and returns the termination status of that child in the buffer pointed to bystatus
.
Explain
- The
wait()
system call does the following:- If no child of the calling process has yet terminated, the call blocks until one of the children terminates. If a child has already terminated by the time of the call, wait() returns immediately.
- If status is not NULL, information about how the child terminated is returned in
the integer to which
status
points. - The kernel adds the process CPU times and resource usage statistics to running totals for all children of this parent process.
Example
The waitpid()
system call
The wait() system call has a number of limitations, which waitpid() was designed to address:
- If a parent process has created multiple children, it is not possible to
wait()
for the completion of a specific child; we can only wait for the next child that terminate - If no child has yet terminated,
wait()
always blocks. Sometimes, it would be preferable to perform a nonblocking wait so that if no child has yet terminated, we obtain an immediate indication of this fact. - Using
wait()
, we can find out only about children that have terminated. It is not possible to be notified when a child is stopped by a signal (such asSIGSTOP
orSIGTTIN
) or when a stopped child is resumed by delivery of aSIGCONT
signal.
Explain
-
The return value and
status
arguments are the same as for `wait(). -
The
pid
arg enables the selection of the child to be waited for, as follows:- If
pid
> 0, wait for the child whoseprocess ID
equalspid
. - If
pid
== 0, wait for any child in the sameprocess group
as the caller (parent). - If
pid
< -1, wait for any child whoseprocess group
identifier == abs(pid
). - If
pid
== -1, wait for any child (wait(int *status)
<==>waitpid(-1, int *status, 0)
).
- If
-
The
options
arg is a bit mask that can include (OR) zero or more of the following flags:
Flag | Description |
---|---|
WUNTRACED | In addition to returning information about terminated children, also return information when a child is stopped by a signal. |
WCONTINUED (since Linux 2.6.10) | Also return status information about stopped children that have been resumed by delivery of a SIGCONT signal. |
WNOHANG | If no child specified by pid has yet changed state, then return immediately, instead of blocking (i.e., perform a “poll”). In this case, the return value of waitpid() is 0. If the calling process has no children that match the specification in pid, waitpid() fails with the error ECHILD . |
Example
The status
value
The status value returned by wait()
and waitpid()
allows us to distinguish the following events for the child:
- The child terminated by calling
_exit()
(orexit()
), specifying an integer exit status. - The child was terminated by the delivery of an unhandled signal.
- The child was stopped by a signal, and
waitpid()
was called with theWUNTRACED
flag. - The child was resumed by a
SIGCONT
signal, andwaitpid()
was called with theWCONTINUED
flag.
We use the term wait status
to encompass all of the above cases. The designation
termination status
is used to refer to the first two cases (variable $?
in shell).
Although defined as an int
, only the bottom 2 bytes of the value pointed to by
status are actually used. The way in which these 2 bytes are filled depends on which
of the above events occurred for the child, as depicted below:
The <sys/wait.h>
header file defines a standard set of macros that can be used to
dissect a wait status value. When applied to a status value returned by wait()
or
waitpid()
, only one of the macros in the list below will return true. Additional macros are provided to further dissect the status value, as noted in the list.
Macros | Description |
---|---|
WIFEXITED(status) | This macro returns true if the child process exited normally. |
WEXITSTATUS(status) | Only defined if WIFEXITED(status) returned true. Returns the exit status of a normally terminated child. |
WIFSIGNALED(status) | This macro returns true if the child process was killed by a signal. |
WTERMSIG(status) | [Only defined if WIFSIGNALED() returned true]Returns the number of the signal that caused the child process to terminate |
WCOREDUMP(status) | [Only defined if WIFSIGNALED() returned true]Returns true if the child process produced a core dump file |
WIFSTOPPED(status) | This macro returns true if the child process was stopped by a signal. |
WSTOPSIG(status) | [Only defined if WIFSTOPPED returned true]Returns the number of the signal that stopped the process |
WIFCONTINUED(status) | This macro returns true if the child was resumed by delivery of SIGCONT . |