mirror of https://github.com/mkerrisk/man-pages
717 lines
19 KiB
Groff
717 lines
19 KiB
Groff
.\" Copyright (c) 1993 by Thomas Koenig <ig25@rz.uni-karlsruhe.de>
|
|
.\" and Copyright (c) 2004 by Michael Kerrisk <mtk.manpages@gmail.com>
|
|
.\"
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
.\" preserved on all copies.
|
|
.\"
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
.\" permission notice identical to this one.
|
|
.\"
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
.\" have taken the same level of care in the production of this manual,
|
|
.\" which is licensed free of charge, as they might when working
|
|
.\" professionally.
|
|
.\"
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.\" Modified Sat Jul 24 13:30:06 1993 by Rik Faith <faith@cs.unc.edu>
|
|
.\" Modified Sun Aug 21 17:42:42 1994 by Rik Faith <faith@cs.unc.edu>
|
|
.\" (Thanks to Koen Holtman <koen@win.tue.nl>)
|
|
.\" Modified Wed May 17 15:54:12 1995 by Rik Faith <faith@cs.unc.edu>
|
|
.\" To remove *'s from status in macros (Thanks to Michael Shields).
|
|
.\" Modified as suggested by Nick Duffek <nsd@bbc.com>, aeb, 960426
|
|
.\" Modified Mon Jun 23 14:09:52 1997 by aeb - add EINTR.
|
|
.\" Modified Thu Nov 26 02:12:45 1998 by aeb - add SIGCHLD stuff.
|
|
.\" Modified Mon Jul 24 21:37:38 2000 by David A. Wheeler
|
|
.\" <dwheeler@dwheeler.com> - noted thread issues.
|
|
.\" Modified 26 Jun 01 by Michael Kerrisk
|
|
.\" Added __WCLONE, __WALL, and __WNOTHREAD descriptions
|
|
.\" Modified 2001-09-25, aeb
|
|
.\" Modified 26 Jun 01 by Michael Kerrisk, <mtk.manpages@gmail.com>
|
|
.\" Updated notes on setting disposition of SIGCHLD to SIG_IGN
|
|
.\" 2004-11-11, mtk
|
|
.\" Added waitid(2); added WCONTINUED and WIFCONTINUED()
|
|
.\" Added text on SA_NOCLDSTOP
|
|
.\" Updated discussion of SA_NOCLDWAIT to reflect 2.6 behavior
|
|
.\" Much other text rewritten
|
|
.\" 2005-05-10, mtk, __W* flags can't be used with waitid()
|
|
.\" 2008-07-04, mtk, removed erroneous text about SA_NOCLDSTOP
|
|
.\"
|
|
.TH WAIT 2 2020-04-11 "Linux" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
wait, waitpid, waitid \- wait for process to change state
|
|
.SH SYNOPSIS
|
|
.B #include <sys/types.h>
|
|
.br
|
|
.B #include <sys/wait.h>
|
|
.PP
|
|
.BI "pid_t wait(int *" "wstatus" );
|
|
.PP
|
|
.BI "pid_t waitpid(pid_t " pid ", int *" wstatus ", int " options );
|
|
.PP
|
|
.BI "int waitid(idtype_t " idtype ", id_t " id \
|
|
", siginfo_t *" infop ", int " options );
|
|
/* This is the glibc and POSIX interface; see
|
|
NOTES for information on the raw system call. */
|
|
.PP
|
|
.in -4n
|
|
Feature Test Macro Requirements for glibc (see
|
|
.BR feature_test_macros (7)):
|
|
.in
|
|
.PP
|
|
.ad l
|
|
.PD 0
|
|
.BR waitid ():
|
|
.RS 4
|
|
Since glibc 2.26:
|
|
_XOPEN_SOURCE >= 500 ||
|
|
.\" (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
|
|
_POSIX_C_SOURCE\ >=\ 200809L
|
|
.br
|
|
Glibc 2.25 and earlier:
|
|
_XOPEN_SOURCE
|
|
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE\ >=\ 200809L
|
|
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE
|
|
.RE
|
|
.PD
|
|
.ad
|
|
.SH DESCRIPTION
|
|
All of these system calls are used to wait for state changes
|
|
in a child of the calling process, and obtain information
|
|
about the child whose state has changed.
|
|
A state change is considered to be: the child terminated;
|
|
the child was stopped by a signal; or the child was resumed by a signal.
|
|
In the case of a terminated child, performing a wait allows
|
|
the system to release the resources associated with the child;
|
|
if a wait is not performed, then the terminated child remains in
|
|
a "zombie" state (see NOTES below).
|
|
.PP
|
|
If a child has already changed state, then these calls return immediately.
|
|
Otherwise, they block until either a child changes state or
|
|
a signal handler interrupts the call (assuming that system calls
|
|
are not automatically restarted using the
|
|
.B SA_RESTART
|
|
flag of
|
|
.BR sigaction (2)).
|
|
In the remainder of this page, a child whose state has changed
|
|
and which has not yet been waited upon by one of these system
|
|
calls is termed
|
|
.IR waitable .
|
|
.SS wait() and waitpid()
|
|
The
|
|
.BR wait ()
|
|
system call suspends execution of the calling thread until one of its
|
|
children terminates.
|
|
The call
|
|
.I wait(&wstatus)
|
|
is equivalent to:
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
waitpid(\-1, &wstatus, 0);
|
|
.EE
|
|
.in
|
|
.PP
|
|
The
|
|
.BR waitpid ()
|
|
system call suspends execution of the calling thread until a
|
|
child specified by
|
|
.I pid
|
|
argument has changed state.
|
|
By default,
|
|
.BR waitpid ()
|
|
waits only for terminated children, but this behavior is modifiable
|
|
via the
|
|
.I options
|
|
argument, as described below.
|
|
.PP
|
|
The value of
|
|
.I pid
|
|
can be:
|
|
.IP "< \-1"
|
|
meaning wait for any child process whose process group ID is
|
|
equal to the absolute value of
|
|
.IR pid .
|
|
.IP \-1
|
|
meaning wait for any child process.
|
|
.IP 0
|
|
meaning wait for any child process whose process group ID is
|
|
equal to that of the calling process at the time of the call to
|
|
.BR waitpid ().
|
|
.IP "> 0"
|
|
meaning wait for the child whose process ID is equal to the
|
|
value of
|
|
.IR pid .
|
|
.PP
|
|
The value of
|
|
.I options
|
|
is an OR of zero or more of the following constants:
|
|
.TP
|
|
.B WNOHANG
|
|
return immediately if no child has exited.
|
|
.TP
|
|
.B WUNTRACED
|
|
also return if a child has stopped
|
|
(but not traced via
|
|
.BR ptrace (2)).
|
|
Status for
|
|
.I traced
|
|
children which have stopped is provided
|
|
even if this option is not specified.
|
|
.TP
|
|
.BR WCONTINUED " (since Linux 2.6.10)"
|
|
also return if a stopped child has been resumed by delivery of
|
|
.BR SIGCONT .
|
|
.PP
|
|
(For Linux-only options, see below.)
|
|
.PP
|
|
If
|
|
.I wstatus
|
|
is not NULL,
|
|
.BR wait ()
|
|
and
|
|
.BR waitpid ()
|
|
store status information in the \fIint\fP to which it points.
|
|
This integer can be inspected with the following macros (which
|
|
take the integer itself as an argument, not a pointer to it,
|
|
as is done in
|
|
.BR wait ()
|
|
and
|
|
.BR waitpid ()!):
|
|
.TP
|
|
.BI WIFEXITED( wstatus )
|
|
returns true if the child terminated normally, that is,
|
|
by calling
|
|
.BR exit (3)
|
|
or
|
|
.BR _exit (2),
|
|
or by returning from main().
|
|
.TP
|
|
.BI WEXITSTATUS( wstatus )
|
|
returns the exit status of the child.
|
|
This consists of the least significant 8 bits of the
|
|
.I status
|
|
argument that the child specified in a call to
|
|
.BR exit (3)
|
|
or
|
|
.BR _exit (2)
|
|
or as the argument for a return statement in main().
|
|
This macro should be employed only if
|
|
.B WIFEXITED
|
|
returned true.
|
|
.TP
|
|
.BI WIFSIGNALED( wstatus )
|
|
returns true if the child process was terminated by a signal.
|
|
.TP
|
|
.BI WTERMSIG( wstatus )
|
|
returns the number of the signal that caused the child process to
|
|
terminate.
|
|
This macro should be employed only if
|
|
.B WIFSIGNALED
|
|
returned true.
|
|
.TP
|
|
.BI WCOREDUMP( wstatus )
|
|
returns true if the child produced a core dump (see
|
|
.BR core (5)).
|
|
This macro should be employed only if
|
|
.B WIFSIGNALED
|
|
returned true.
|
|
.IP
|
|
This macro is not specified in POSIX.1-2001 and is not available on
|
|
some UNIX implementations (e.g., AIX, SunOS).
|
|
Therefore, enclose its use inside
|
|
.IR "#ifdef WCOREDUMP ... #endif" .
|
|
.TP
|
|
.BI WIFSTOPPED( wstatus )
|
|
returns true if the child process was stopped by delivery of a signal;
|
|
this is possible only if the call was done using
|
|
.B WUNTRACED
|
|
or when the child is being traced (see
|
|
.BR ptrace (2)).
|
|
.TP
|
|
.BI WSTOPSIG( wstatus )
|
|
returns the number of the signal which caused the child to stop.
|
|
This macro should be employed only if
|
|
.B WIFSTOPPED
|
|
returned true.
|
|
.TP
|
|
.BI WIFCONTINUED( wstatus )
|
|
(since Linux 2.6.10)
|
|
returns true if the child process was resumed by delivery of
|
|
.BR SIGCONT .
|
|
.SS waitid()
|
|
The
|
|
.BR waitid ()
|
|
system call (available since Linux 2.6.9) provides more precise
|
|
control over which child state changes to wait for.
|
|
.PP
|
|
The
|
|
.I idtype
|
|
and
|
|
.I id
|
|
arguments select the child(ren) to wait for, as follows:
|
|
.IP "\fIidtype\fP == \fBP_PID\fP"
|
|
Wait for the child whose process ID matches
|
|
.IR id .
|
|
.IP "\fIidtype\fP == \fBP_PIDFD\fP (since Linux 5.4)"
|
|
.\" commit 3695eae5fee0605f316fbaad0b9e3de791d7dfaf
|
|
Wait for the child referred to by the PID file descriptor specified in
|
|
.IR id .
|
|
(See
|
|
.BR pidfd_open (2)
|
|
for further information on PID file descriptors.)
|
|
.IP "\fIidtype\fP == \fBP_PGID\fP"
|
|
Wait for any child whose process group ID matches
|
|
.IR id .
|
|
Since Linux 5.4,
|
|
.\" commit 821cc7b0b205c0df64cce59aacc330af251fa8f7
|
|
if
|
|
.I id
|
|
is zero, then wait for any child that is in the same process group
|
|
as the caller's process group at the time of the call.
|
|
.IP "\fIidtype\fP == \fBP_ALL\fP"
|
|
Wait for any child;
|
|
.I id
|
|
is ignored.
|
|
.PP
|
|
The child state changes to wait for are specified by ORing
|
|
one or more of the following flags in
|
|
.IR options :
|
|
.TP
|
|
.B WEXITED
|
|
Wait for children that have terminated.
|
|
.TP
|
|
.B WSTOPPED
|
|
Wait for children that have been stopped by delivery of a signal.
|
|
.TP
|
|
.B WCONTINUED
|
|
Wait for (previously stopped) children that have been
|
|
resumed by delivery of
|
|
.BR SIGCONT .
|
|
.PP
|
|
The following flags may additionally be ORed in
|
|
.IR options :
|
|
.TP
|
|
.B WNOHANG
|
|
As for
|
|
.BR waitpid ().
|
|
.TP
|
|
.B WNOWAIT
|
|
Leave the child in a waitable state; a later wait call
|
|
can be used to again retrieve the child status information.
|
|
.PP
|
|
Upon successful return,
|
|
.BR waitid ()
|
|
fills in the following fields of the
|
|
.I siginfo_t
|
|
structure pointed to by
|
|
.IR infop :
|
|
.TP
|
|
\fIsi_pid\fP
|
|
The process ID of the child.
|
|
.TP
|
|
\fIsi_uid\fP
|
|
The real user ID of the child.
|
|
(This field is not set on most other implementations.)
|
|
.TP
|
|
\fIsi_signo\fP
|
|
Always set to
|
|
.BR SIGCHLD .
|
|
.TP
|
|
\fIsi_status\fP
|
|
Either the exit status of the child, as given to
|
|
.BR _exit (2)
|
|
(or
|
|
.BR exit (3)),
|
|
or the signal that caused the child to terminate, stop, or continue.
|
|
The
|
|
.I si_code
|
|
field can be used to determine how to interpret this field.
|
|
.TP
|
|
\fIsi_code\fP
|
|
Set to one of:
|
|
.B CLD_EXITED
|
|
(child called
|
|
.BR _exit (2));
|
|
.B CLD_KILLED
|
|
(child killed by signal);
|
|
.B CLD_DUMPED
|
|
(child killed by signal, and dumped core);
|
|
.B CLD_STOPPED
|
|
(child stopped by signal);
|
|
.B CLD_TRAPPED
|
|
(traced child has trapped); or
|
|
.B CLD_CONTINUED
|
|
(child continued by
|
|
.BR SIGCONT ).
|
|
.PP
|
|
If
|
|
.B WNOHANG
|
|
was specified in
|
|
.I options
|
|
and there were no children in a waitable state, then
|
|
.BR waitid ()
|
|
returns 0 immediately and
|
|
the state of the
|
|
.I siginfo_t
|
|
structure pointed to by
|
|
.I infop
|
|
depends on the implementation.
|
|
To (portably) distinguish this case from that where a child was in a
|
|
waitable state, zero out the
|
|
.I si_pid
|
|
field before the call and check for a nonzero value in this field
|
|
after the call returns.
|
|
.PP
|
|
POSIX.1-2008 Technical Corrigendum 1 (2013) adds the requirement that when
|
|
.B WNOHANG
|
|
is specified in
|
|
.I options
|
|
and there were no children in a waitable state, then
|
|
.BR waitid ()
|
|
should zero out the
|
|
.I si_pid
|
|
and
|
|
.I si_signo
|
|
fields of the structure.
|
|
On Linux and other implementations that adhere to this requirement,
|
|
it is not necessary to zero out the
|
|
.I si_pid
|
|
field before calling
|
|
.BR waitid ().
|
|
However,
|
|
not all implementations follow the POSIX.1 specification on this point.
|
|
.\" POSIX.1-2001 leaves this possibility unspecified; most
|
|
.\" implementations (including Linux) zero out the structure
|
|
.\" in this case, but at least one implementation (AIX 5.1)
|
|
.\" does not -- MTK Nov 04
|
|
.SH RETURN VALUE
|
|
.BR wait ():
|
|
on success, returns the process ID of the terminated child;
|
|
on error, \-1 is returned.
|
|
.PP
|
|
.BR waitpid ():
|
|
on success, returns the process ID of the child whose state has changed;
|
|
if
|
|
.B WNOHANG
|
|
was specified and one or more child(ren) specified by
|
|
.I pid
|
|
exist, but have not yet changed state, then 0 is returned.
|
|
On error, \-1 is returned.
|
|
.PP
|
|
.BR waitid ():
|
|
returns 0 on success or
|
|
if
|
|
.B WNOHANG
|
|
was specified and no child(ren) specified by
|
|
.I id
|
|
has yet changed state;
|
|
on error, \-1 is returned.
|
|
.\" FIXME As reported by Vegard Nossum, if infop is NULL, then waitid()
|
|
.\" returns the PID of the child. Either this is a bug, or it is intended
|
|
.\" behavior that needs to be documented. See my Jan 2009 LKML mail
|
|
.\" "waitid() return value strangeness when infop is NULL".
|
|
.PP
|
|
Each of these calls sets
|
|
.I errno
|
|
to an appropriate value in the case of an error.
|
|
.SH ERRORS
|
|
.TP
|
|
.B ECHILD
|
|
(for
|
|
.BR wait ())
|
|
The calling process does not have any unwaited-for children.
|
|
.TP
|
|
.B ECHILD
|
|
(for
|
|
.BR waitpid ()
|
|
or
|
|
.BR waitid ())
|
|
The process specified by
|
|
.I pid
|
|
.RB ( waitpid ())
|
|
or
|
|
.I idtype
|
|
and
|
|
.I id
|
|
.RB ( waitid ())
|
|
does not exist or is not a child of the calling process.
|
|
(This can happen for one's own child if the action for
|
|
.B SIGCHLD
|
|
is set to
|
|
.BR SIG_IGN .
|
|
See also the \fILinux Notes\fP section about threads.)
|
|
.TP
|
|
.B EINTR
|
|
.B WNOHANG
|
|
was not set and an unblocked signal or a
|
|
.B SIGCHLD
|
|
was caught; see
|
|
.BR signal (7).
|
|
.TP
|
|
.B EINVAL
|
|
The
|
|
.I options
|
|
argument was invalid.
|
|
.SH CONFORMING TO
|
|
SVr4, 4.3BSD, POSIX.1-2001.
|
|
.SH NOTES
|
|
A child that terminates, but has not been waited for becomes a "zombie".
|
|
The kernel maintains a minimal set of information about the zombie
|
|
process (PID, termination status, resource usage information)
|
|
in order to allow the parent to later perform a wait to obtain
|
|
information about the child.
|
|
As long as a zombie is not removed from the system via a wait,
|
|
it will consume a slot in the kernel process table, and if
|
|
this table fills, it will not be possible to create further processes.
|
|
If a parent process terminates, then its "zombie" children (if any)
|
|
are adopted by
|
|
.BR init (1),
|
|
(or by the nearest "subreaper" process as defined through the use of the
|
|
.BR prctl (2)
|
|
.B PR_SET_CHILD_SUBREAPER
|
|
operation);
|
|
.BR init (1)
|
|
automatically performs a wait to remove the zombies.
|
|
.PP
|
|
POSIX.1-2001 specifies that if the disposition of
|
|
.B SIGCHLD
|
|
is set to
|
|
.B SIG_IGN
|
|
or the
|
|
.B SA_NOCLDWAIT
|
|
flag is set for
|
|
.B SIGCHLD
|
|
(see
|
|
.BR sigaction (2)),
|
|
then children that terminate do not become zombies and a call to
|
|
.BR wait ()
|
|
or
|
|
.BR waitpid ()
|
|
will block until all children have terminated, and then fail with
|
|
.I errno
|
|
set to
|
|
.BR ECHILD .
|
|
(The original POSIX standard left the behavior of setting
|
|
.B SIGCHLD
|
|
to
|
|
.B SIG_IGN
|
|
unspecified.
|
|
Note that even though the default disposition of
|
|
.B SIGCHLD
|
|
is "ignore", explicitly setting the disposition to
|
|
.B SIG_IGN
|
|
results in different treatment of zombie process children.)
|
|
.PP
|
|
Linux 2.6 conforms to the POSIX requirements.
|
|
However, Linux 2.4 (and earlier) does not:
|
|
if a
|
|
.BR wait ()
|
|
or
|
|
.BR waitpid ()
|
|
call is made while
|
|
.B SIGCHLD
|
|
is being ignored, the call behaves just as though
|
|
.B SIGCHLD
|
|
were not being ignored, that is, the call blocks until the next child
|
|
terminates and then returns the process ID and status of that child.
|
|
.SS Linux notes
|
|
In the Linux kernel, a kernel-scheduled thread is not a distinct
|
|
construct from a process.
|
|
Instead, a thread is simply a process
|
|
that is created using the Linux-unique
|
|
.BR clone (2)
|
|
system call; other routines such as the portable
|
|
.BR pthread_create (3)
|
|
call are implemented using
|
|
.BR clone (2).
|
|
Before Linux 2.4, a thread was just a special case of a process,
|
|
and as a consequence one thread could not wait on the children
|
|
of another thread, even when the latter belongs to the same thread group.
|
|
However, POSIX prescribes such functionality, and since Linux 2.4
|
|
a thread can, and by default will, wait on children of other threads
|
|
in the same thread group.
|
|
.PP
|
|
The following Linux-specific
|
|
.I options
|
|
are for use with children created using
|
|
.BR clone (2);
|
|
they can also, since Linux 4.7,
|
|
.\" commit 91c4e8ea8f05916df0c8a6f383508ac7c9e10dba
|
|
be used with
|
|
.BR waitid ():
|
|
.TP
|
|
.B __WCLONE
|
|
.\" since 0.99pl10
|
|
Wait for "clone" children only.
|
|
If omitted, then wait for "non-clone" children only.
|
|
(A "clone" child is one which delivers no signal, or a signal other than
|
|
.B SIGCHLD
|
|
to its parent upon termination.)
|
|
This option is ignored if
|
|
.B __WALL
|
|
is also specified.
|
|
.TP
|
|
.BR __WALL " (since Linux 2.4)"
|
|
.\" since patch-2.3.48
|
|
Wait for all children, regardless of
|
|
type ("clone" or "non-clone").
|
|
.TP
|
|
.BR __WNOTHREAD " (since Linux 2.4)"
|
|
.\" since patch-2.4.0-test8
|
|
Do not wait for children of other threads in
|
|
the same thread group.
|
|
This was the default before Linux 2.4.
|
|
.PP
|
|
Since Linux 4.7,
|
|
.\" commit bf959931ddb88c4e4366e96dd22e68fa0db9527c
|
|
.\" prevents cases where an unreapable zombie is created if
|
|
.\" /sbin/init doesn't use __WALL.
|
|
the
|
|
.B __WALL
|
|
flag is automatically implied if the child is being ptraced.
|
|
.SS C library/kernel differences
|
|
.BR wait ()
|
|
is actually a library function that (in glibc) is implemented as a call to
|
|
.BR wait4 (2).
|
|
.PP
|
|
On some architectures, there is no
|
|
.BR waitpid ()
|
|
system call;
|
|
.\" e.g., i386 has the system call, but not x86-64
|
|
instead, this interface is implemented via a C library
|
|
wrapper function that calls
|
|
.BR wait4 (2).
|
|
.PP
|
|
The raw
|
|
.BR waitid ()
|
|
system call takes a fifth argument, of type
|
|
.IR "struct rusage\ *" .
|
|
If this argument is non-NULL,
|
|
then it is used to return resource usage information about the child,
|
|
in the same manner as
|
|
.BR wait4 (2).
|
|
See
|
|
.BR getrusage (2)
|
|
for details.
|
|
.SH BUGS
|
|
According to POSIX.1-2008, an application calling
|
|
.BR waitid ()
|
|
must ensure that
|
|
.I infop
|
|
points to a
|
|
.I siginfo_t
|
|
structure (i.e., that it is a non-null pointer).
|
|
On Linux, if
|
|
.I infop
|
|
is NULL,
|
|
.BR waitid ()
|
|
succeeds, and returns the process ID of the waited-for child.
|
|
Applications should avoid relying on this inconsistent,
|
|
nonstandard, and unnecessary feature.
|
|
.SH EXAMPLES
|
|
.\" fork.2 refers to this example program.
|
|
The following program demonstrates the use of
|
|
.BR fork (2)
|
|
and
|
|
.BR waitpid ().
|
|
The program creates a child process.
|
|
If no command-line argument is supplied to the program,
|
|
then the child suspends its execution using
|
|
.BR pause (2),
|
|
to allow the user to send signals to the child.
|
|
Otherwise, if a command-line argument is supplied,
|
|
then the child exits immediately,
|
|
using the integer supplied on the command line as the exit status.
|
|
The parent process executes a loop that monitors the child using
|
|
.BR waitpid (),
|
|
and uses the W*() macros described above to analyze the wait status value.
|
|
.PP
|
|
The following shell session demonstrates the use of the program:
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
.RB "$" " ./a.out &"
|
|
Child PID is 32360
|
|
[1] 32359
|
|
.RB "$" " kill \-STOP 32360"
|
|
stopped by signal 19
|
|
.RB "$" " kill \-CONT 32360"
|
|
continued
|
|
.RB "$" " kill \-TERM 32360"
|
|
killed by signal 15
|
|
[1]+ Done ./a.out
|
|
$
|
|
.EE
|
|
.in
|
|
.SS Program source
|
|
\&
|
|
.EX
|
|
#include <sys/wait.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
pid_t cpid, w;
|
|
int wstatus;
|
|
|
|
cpid = fork();
|
|
if (cpid == \-1) {
|
|
perror("fork");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (cpid == 0) { /* Code executed by child */
|
|
printf("Child PID is %ld\en", (long) getpid());
|
|
if (argc == 1)
|
|
pause(); /* Wait for signals */
|
|
_exit(atoi(argv[1]));
|
|
|
|
} else { /* Code executed by parent */
|
|
do {
|
|
w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
|
|
if (w == \-1) {
|
|
perror("waitpid");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (WIFEXITED(wstatus)) {
|
|
printf("exited, status=%d\en", WEXITSTATUS(wstatus));
|
|
} else if (WIFSIGNALED(wstatus)) {
|
|
printf("killed by signal %d\en", WTERMSIG(wstatus));
|
|
} else if (WIFSTOPPED(wstatus)) {
|
|
printf("stopped by signal %d\en", WSTOPSIG(wstatus));
|
|
} else if (WIFCONTINUED(wstatus)) {
|
|
printf("continued\en");
|
|
}
|
|
} while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
}
|
|
.EE
|
|
.SH SEE ALSO
|
|
.BR _exit (2),
|
|
.BR clone (2),
|
|
.BR fork (2),
|
|
.BR kill (2),
|
|
.BR ptrace (2),
|
|
.BR sigaction (2),
|
|
.BR signal (2),
|
|
.BR wait4 (2),
|
|
.BR pthread_create (3),
|
|
.BR core (5),
|
|
.BR credentials (7),
|
|
.BR signal (7)
|