-.\" Hey Emacs! This file is -*- nroff -*- source.
-.\"
.\" 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.
.\"
.\" Formatted or processed versions of this manual, if unaccompanied by
.\" the source, must acknowledge the copyright and authors of this work.
-.\" License.
+.\" %%%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>
.\" 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 2009-04-21 "Linux" "Linux Programmer's Manual"
+.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>
-.sp
-.BI "pid_t wait(int *" "status" );
-
-.BI "pid_t waitpid(pid_t " pid ", int *" status ", int " options );
-
+.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 );
-.sp
+ /* 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
-.sp
+.PP
+.ad l
+.PD 0
.BR waitid ():
-_SVID_SOURCE || _XOPEN_SOURCE
+.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
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
+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
and which has not yet been waited upon by one of these system
calls is termed
.IR waitable .
-.SS "wait() and waitpid()"
+.SS wait() and waitpid()
The
.BR wait ()
-system call suspends execution of the calling process until one of its
+system call suspends execution of the calling thread until one of its
children terminates.
The call
-.I wait(&status)
+.I wait(&wstatus)
is equivalent to:
-.nf
-
- waitpid(\-1, &status, 0);
-.fi
-
+.PP
+.in +4n
+.EX
+waitpid(\-1, &wstatus, 0);
+.EE
+.in
+.PP
The
.BR waitpid ()
-system call suspends execution of the calling process until a
+system call suspends execution of the calling thread until a
child specified by
.I pid
argument has changed state.
via the
.I options
argument, as described below.
-
+.PP
The value of
.I pid
can be:
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.
+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
The value of
.I options
is an OR of zero or more of the following constants:
-.TP 12
+.TP
.B WNOHANG
return immediately if no child has exited.
.TP
(For Linux-only options, see below.)
.PP
If
-.I status
+.I wstatus
is not NULL,
.BR wait ()
and
and
.BR waitpid ()!):
.TP
-.BI WIFEXITED( status )
+.BI WIFEXITED( wstatus )
returns true if the child terminated normally, that is,
by calling
.BR exit (3)
.BR _exit (2),
or by returning from main().
.TP
-.BI WEXITSTATUS( status )
+.BI WEXITSTATUS( wstatus )
returns the exit status of the child.
This consists of the least significant 8 bits of the
.I status
or
.BR _exit (2)
or as the argument for a return statement in main().
-This macro should only be employed if
+This macro should be employed only if
.B WIFEXITED
returned true.
.TP
-.BI WIFSIGNALED( status )
+.BI WIFSIGNALED( wstatus )
returns true if the child process was terminated by a signal.
.TP
-.BI WTERMSIG( status )
+.BI WTERMSIG( wstatus )
returns the number of the signal that caused the child process to
terminate.
-This macro should only be employed if
+This macro should be employed only if
.B WIFSIGNALED
returned true.
.TP
-.BI WCOREDUMP( status )
-returns true if the child produced a core dump.
-This macro should only be employed if
+.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).
-Only use this enclosed in #ifdef WCOREDUMP ... #endif.
+some UNIX implementations (e.g., AIX, SunOS).
+Therefore, enclose its use inside
+.IR "#ifdef WCOREDUMP ... #endif" .
.TP
-.BI WIFSTOPPED( status )
+.BI WIFSTOPPED( wstatus )
returns true if the child process was stopped by delivery of a signal;
-this is only possible if the call was done using
+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( status )
+.BI WSTOPSIG( wstatus )
returns the number of the signal which caused the child to stop.
-This macro should only be employed if
+This macro should be employed only if
.B WIFSTOPPED
returned true.
.TP
-.BI WIFCONTINUED( status )
+.BI WIFCONTINUED( wstatus )
(since Linux 2.6.10)
returns true if the child process was resumed by delivery of
.BR SIGCONT .
-.SS "waitid()"
+.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
.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
The child state changes to wait for are specified by ORing
one or more of the following flags in
.IR options :
-.TP 12
+.TP
.B WEXITED
Wait for children that have terminated.
.TP
.PP
The following flags may additionally be ORed in
.IR options :
-.TP 12
+.TP
.B WNOHANG
As for
.BR waitpid ().
.I siginfo_t
structure pointed to by
.IR infop :
-.TP 12
+.TP
\fIsi_pid\fP
The process ID of the child.
.TP
.I siginfo_t
structure pointed to by
.I infop
-is unspecified.
-.\" POSIX.1-2001 leaves this possibility unspecified; most
-.\" implementations (including Linux) zero out the structure
-.\" in this case, but at at least one implementation (AIX 5.1)
-.\" does not -- MTK Nov 04
-To distinguish this case from that where a child was in a
+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.
-.SH "RETURN VALUE"
+.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
.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
.I id
has yet changed state;
on error, \-1 is returned.
-.\" FIXME: As reported by Vegard Nossum, if infop is NULL, then waitid()
+.\" 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.
The
.I options
argument was invalid.
-.SH "CONFORMING TO"
+.SH CONFORMING TO
SVr4, 4.3BSD, POSIX.1-2001.
.SH NOTES
A child that terminates, but has not been waited for becomes a "zombie".
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 (8),
-which automatically performs a wait to remove the zombies.
-
+.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
is "ignore", explicitly setting the disposition to
.B SIG_IGN
results in different treatment of zombie process children.)
-Linux 2.6 conforms to this specification.
+.PP
+Linux 2.6 conforms to the POSIX requirements.
However, Linux 2.4 (and earlier) does not:
if a
.BR wait ()
.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
+.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
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.
-.LP
+.PP
The following Linux-specific
.I options
are for use with children created using
.BR clone (2);
-they cannot be used with
+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.
+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.)
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 EXAMPLE
.\" fork.2 refers to this example program.
The following program demonstrates the use of
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
-.nf
-
+.EX
.RB "$" " ./a.out &"
Child PID is 32360
[1] 32359
killed by signal 15
[1]+ Done ./a.out
$
-.fi
+.EE
.in
.SS Program source
\&
-.nf
+.EX
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
main(int argc, char *argv[])
{
pid_t cpid, w;
- int status;
+ int wstatus;
cpid = fork();
if (cpid == \-1) {
}
if (cpid == 0) { /* Code executed by child */
- printf("Child PID is %ld\\n", (long) getpid());
+ 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, &status, WUNTRACED | WCONTINUED);
+ w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
if (w == \-1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
- if (WIFEXITED(status)) {
- printf("exited, status=%d\\n", WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- printf("killed by signal %d\\n", WTERMSIG(status));
- } else if (WIFSTOPPED(status)) {
- printf("stopped by signal %d\\n", WSTOPSIG(status));
- } else if (WIFCONTINUED(status)) {
- printf("continued\\n");
+ 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(status) && !WIFSIGNALED(status));
+ } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
exit(EXIT_SUCCESS);
}
}
-.fi
-.SH "SEE ALSO"
+.EE
+.SH SEE ALSO
.BR _exit (2),
.BR clone (2),
.BR fork (2),
.BR signal (2),
.BR wait4 (2),
.BR pthread_create (3),
+.BR core (5),
.BR credentials (7),
.BR signal (7)