diff options
Diffstat (limited to '')
-rw-r--r-- | man2/wait.2 | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/man2/wait.2 b/man2/wait.2 new file mode 100644 index 0000000..cbd851e --- /dev/null +++ b/man2/wait.2 @@ -0,0 +1,720 @@ +.\" Copyright (c) 1993 by Thomas Koenig <ig25@rz.uni-karlsruhe.de> +.\" and Copyright (c) 2004 by Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" 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 2023-05-03 "Linux man-pages 6.05.01" +.SH NAME +wait, waitpid, waitid \- wait for process to change state +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <sys/wait.h> +.PP +.BI "pid_t wait(int *_Nullable " "wstatus" ); +.BI "pid_t waitpid(pid_t " pid ", int *_Nullable " 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. */ +.fi +.PP +.RS -4 +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.RE +.PP +.BR waitid (): +.nf + Since glibc 2.26: + _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L +.\" (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) + glibc 2.25 and earlier: + _XOPEN_SOURCE + || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L + || /* glibc <= 2.19: */ _BSD_SOURCE +.fi +.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: +.TP +.RB "< " \-1 +meaning wait for any child process whose process group ID is +equal to the absolute value of +.IR pid . +.TP +.B \-1 +meaning wait for any child process. +.TP +.B 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 (). +.TP +.RB "> " 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: +.TP +.IR idtype " == " \fBP_PID\fP +Wait for the child whose process ID matches +.IR id . +.TP +.IR idtype " == " \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.) +.TP +.IR idtype " == " \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. +.TP +.IR idtype " == " \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 failure, \-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 failure, \-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 failure, \-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 +On failure, each of these calls sets +.I errno +to indicate the error. +.SH ERRORS +.TP +.B EAGAIN +The PID file descriptor specified in +.I id +is nonblocking and the process that it refers to has not terminated. +.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. +.TP +.B ESRCH +(for +.BR wait () +or +.BR waitpid ()) +.I pid +is equal to +.BR INT_MIN . +.SH VERSIONS +.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 STANDARDS +POSIX.1-2008. +.SH HISTORY +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. +.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 +\& +.\" SRC BEGIN (wait.c) +.EX +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <unistd.h> +\& +int +main(int argc, char *argv[]) +{ + int wstatus; + pid_t cpid, w; +\& + cpid = fork(); + if (cpid == \-1) { + perror("fork"); + exit(EXIT_FAILURE); + } +\& + if (cpid == 0) { /* Code executed by child */ + printf("Child PID is %jd\en", (intmax_t) 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 +.\" SRC END +.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) |