1
0
Files
irix-657m-src/eoe/man/man2/wait.2
2022-09-29 17:59:04 +03:00

564 lines
13 KiB
Groff

'\"macro stdmacro
.if n .pH g2.wait @(#)wait 30.2 of 12/25/85
.TH WAIT 2
.Op c p a
.SH NAME
wait, waitpid, wait3 \- wait for child processes to stop or terminate
.SH C SYNOPSIS
\f4#include <sys/types.h>\fP
.br
\f4#include <sys/wait.h>\fP
.PP
\f4pid_t wait (int \(**statptr);\fP
.br
\f4pid_t waitpid (pid_t pid, int \(**statptr, int options);\fP
.PP
\f4#include <sys/types.h>\fP
.br
\f4#include <sys/wait.h>\fP
.br
\f4#include <sys/resource.h>\fP
.PP
\f4pid_t wait3 (int \(**statptr, int options, struct rusage \(**rusage);\fP
.Op
.Op f
.SH NAME
wait \- wait for child processes to stop or terminate
.SH FORTRAN SYNOPSIS
.nf
.B integer function wait (status)
.B integer status
.Op
.fi
.SH DESCRIPTION
\f4wait\f1
suspends the calling process until
one of the immediate children
terminate, or until a child that is
being traced stops because it has hit an event of interest.
The \f4wait\f1 will return
prematurely if a signal is received.
If all child processes stopped or terminated prior to the call
on \f4wait\f1,
return is immediate.
.PP
If the call is successful, the process
.SM ID
of a child is returned.
.Op c p a
.PP
\f4wait3\f1
is \s-1BSD\s+1's extension of
\f4wait\f1.
It provides an alternate interface for programs
that must not block when collecting the status
of child processes.
.PP
\f4waitpid\f1
is \s-1POSIX\s+1's extension of
\f4wait\f1.
The
\f4pid\f1
argument specifies a set of child processes for which status is
requested.
\f4waitpid\f1
only returns the status of a child process from this set.
.Op
.SH PARAMETERS
.PP
.B statptr (all functions):
If
.I statptr\^
is non-zero, 16 bits of information called
.I status
are stored in the low-order 16 bits of the location pointed to by
.IR statptr.
.I Status\^
may be evaluated with the
macros described on \f4wstat\fP(5).
.I Status\^
can be used to differentiate between stopped and terminated child
processes. If the child process terminated,
\f2status\f1
identifies the cause of termination
and passes useful information to the parent.
\f2status\f1
is interpreted as follows:
.IP
If the child process stopped,
the predicate
.BR \s-1WIFSTOPPED\s0 (\(**\f2statptr\fP)
will evaluate to non-zero and
.BR \s-1WSTOPSIG\s0 (\(**\f2statptr\fP)
will return the signal number that caused the process to stop.
(The high-order 8 bits of \f2status\f1 will
contain the signal number and
the low-order 8 bits are set equal to \f4WSTOPFLG\fP.)
.IP
If the child process terminated due to an
\f4exit\f1
call, the predicate
.BR \s-1WIFEXITED\s0 (\(**\f2statptr\fP)
will evaluate to non-zero, and
.BR \s-1WEXITSTATUS\s0 (\(**\f2statptr\fP)
will return the argument that the child process passed to
\f4_exit\f1 or \f4exit\f1,
or the value the child process returned from
.I main
[see
.IR exit (2)].
(The low-order 8 bits of \f2status\f1 will be zero and the
high-order 8 bits
will contain the low-order 8 bits of the argument that the child process
passed to \f4exit\f1.)
.IP
If the child process terminated due to a signal,
the predicate
.BR \s-1WIFSIGNALED\s0 (\(**\f2statptr\fP)
will evaluate to non-zero, and
.BR \s-1WTERMSIG\s0 (\(**\f2statptr\fP)
will return the signal number that caused the termination.
(The high-order 8 bits of \f2status\f1 will be zero and the low-order 8 bits
will contain the number of the signal.)
In addition, if \f4WCOREFLG\fP is set,
a ``core image'' will have been produced [see
.IR signal (2)].
.Op c p a
.PP
.B rusage (wait3):
If
.I rusage
non-zero, a summary of the resources used by the terminated
process and all its
children is returned (this information is currently not available
for stopped processes).
.PP
.B pid (waitpid):
.IP
1) If
.I pid
is equal to \-1, status is requested for any child process.
In this
respect,
\f4waitpid\f1
is then equivalent to
\f4wait\f1.
.IP
2) If
\f2pid\f1
is greater than zero, it specifies the process
.SM ID
of a single
child process for which status is requested.
.IP
3) If
\f2pid\f1
is equal to zero, status is requested for any child process whose
process group
.SM ID
is equal to that of the calling process.
.IP
4) If
\f2pid\f1
is less than \-1, status is requested for any child process whose
process group
.SM ID
is equal to the absolute value of
\f2pid\f1.
.PP
.B options (waitpid and wait3):
The
.I options argument
is constructed from the bitwise inclusive
.SM OR
of zero or more of the following flags, defined in the header
.RI < sys/wait.h >:
.TP 15
\%WNOHANG
The
function will not suspend execution of the calling process if status is
not immediately available for one of the child processes.
.TP
\%WUNTRACED
The status of child processes
that are stopped
due to a
.BR \s-1SIGTTIN\s0 ,
.BR \s-1SIGTTOU\s0 ,
.BR \s-1SIGTSTP\s0 ,
or
.B \s-1SIGSTOP\s0
signal,
and whose status has not yet been reported since they
stopped, are reported to the requesting process.
.PP
If a parent process terminates without waiting for its child processes
to terminate, the parent process
.SM ID
of each child process is set to 1.
This means the initialization process inherits the child processes [see
.IR intro (2)].
.Op
.SH SIGCLD HANDLING
.SM IRIX
has three distinct version of signal routines: System V (\f4signal\fP(2)
and \f4sigset\fP(2)),
4.3\c
.SM BSD
(\f4signal\fP(3B) and \f4sigvec\fP(3B)),
and
.SM POSIX
(\f4sigaction\fP(2)).
Each version has a method by which
a parent can be certain that it waits on all of its children even
if they are executing concurrently.
In each version, the parent installs a signal handler for
.B \s-1SIGCLD\s0
to wait for its children, but the specific code differs in subtle,
albeit vital, ways.
Sample programs below are used to illustrate each of the three methods.
.PP
Note that System V refers to this signal as
.BR \s-1SIGCLD\s0 ,
whereas
.SM BSD
calls it
.BR \s-1SIGCHLD\s0 .
For compatibility with both systems they
are defined to be the same signal number, and may therefore
be used interchangeably.
.\"-----------------------------------
.PP
\f3System V:\fP System V's
.B \s-1SIGCLD\s0
mechanism guarantees that no
.B \s-1SIGCLD\s0
signals will be lost.
It accomplishes this by forcing the process to reinstall the handler
(via \f4signal\fP or \f4sigset\fP calls) when leaving the handler.
Note that whereas \f4signal\fP(2) sets the signal disposition back to
.B \s-1SIG_DFL\s0
each time the handler is called, \f4sigset\fP(2) keeps it installed, so
.B \s-1SIGCLD\s0
is the only signal that demands this reinstallation,
and that only because the installation call allows the kernel to check
for additional instances of the signal that occurred while the
process was executing in the handler.
.Op c p a
The code below is the System V example.
Note that the \f4sigpause\fP(2) creates a window during which
.B \s-1SIGCLD\s0
is not blocked, allowing the parent to enter its handler.
.\"-----------------------------------
.PP
.Ex
/*
* System V example of wait-in-SIGCLD-handler usage
*/
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
static void handler(int);
#define NUMKIDS 4
volatile int kids = NUMKIDS;
main()
{
int i, pid;
sigset(SIGCLD, handler);
sighold(SIGCLD);
for (i = 0; i < NUMKIDS; i++) {
if (fork() == 0) {
printf("Child %d\en", getpid());
exit(0);
}
}
while (kids > 0) {
sigpause(SIGCLD);
sighold(SIGCLD);
}
}
static void
handler(int sig)
{
int pid, status;
printf("Parent (%d) in handler, ", getpid());
pid = wait(&status);
kids--;
printf("child %d, now %d left\en", pid, kids);
/*
* Now reinstall handler & cause SIGCLD to be re-raised
* if any more children exited while we were in here.
*/
sigset(SIGCLD, handler);
}
.Ee
.PP
.SM
\f3BSD:\fP
4.3\c
.SM BSD
solved this problem differently: instead of
guaranteeing that no
.B \s-1SIGCHLD\s0
signals are lost, it provides a
.SM
.B WNOHANG
option to \f4wait3\fP
that allows parent processes to do non-blocking waits in loops,
until no more stopped or zombied children exist.
Note that the handler must be able to deal with the case
in which no applicable children exist; if one or
more children exit while the parent is in the handler, all may get
reaped, yet if one or more
.B \s-1SIGCHLD\s0
signals arrived while the parent was in its handler,
the signal will remain pending, the parent will
reenter the handler, and the \f4wait3\fP call will return 0.
Note that it is not necessary to call \f4sigvec\fP upon exit from the
handler.
.PP
.Ex
/*
* BSD example of wait3-in-SIGCHLD handler usage
*/
#define _BSD_SIGNALS
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
static int handler(int);
#define NUMKIDS 4
volatile int kids = NUMKIDS;
main()
{
int i, pid;
struct sigvec vec;
vec.sv_handler = handler;
vec.sv_mask = sigmask(SIGCHLD);
vec.sv_flags = 0;
sigvec(SIGCHLD, &vec, NULL);
sigsetmask(sigmask(SIGCHLD));
for (i = 0; i < NUMKIDS; i++) {
if (fork() == 0) {
printf("Child %d\en", getpid());
exit(0);
}
}
while (kids > 0) {
sigpause(0);
}
}
static int
handler(int sig)
{
int pid;
int status;
printf("Parent (%d) in handler, ", getpid());
while ((pid = wait3(&status, WNOHANG, NULL)) > 0) {
kids--;
printf("child %d, now %d left\en", pid, kids);
}
}
.Ee
.PP
\f3POSIX:\fP
.SM POSIX
improved on the
.SM BSD
method by providing
\f4waitpid\fP,
that allows a parent to wait on a particular child process if
desired.
In addition, the
.SM IRIX
implementation of \f4sigaction\fP(2)
checks for zombied children upon exit from the system call
if the specified signal was
.B \s-1SIGCLD\s0
and the disposition of the signal handling was changed.
If zombied children exist, another
.B \s-1SIGCLD\s0
is raised.
This solves the problem that occurs when a
parent creates children, but a module that it links with (typically
a libc routine such as \f4system\fP(3)) creates and waits on its own children.
.PP
Two problems have classically arisen in such a scheme: 1) until the advent of
\f4waitpid\f1,
the called routine could not specify which children to wait on;
it therefore looped, waiting and discarding children until the
one (or ones) it had created terminated, and 2) if the called routine
changed the disposition of
.B \s-1SIGCLD\s0
and then restored the previous handler upon exit, children
of the parent (calling) process that had terminated while the called
routine executed would be missed in the parent, because the called routine's
.B \s-1SIGCLD\s0
handler would reap and discard those children.
The addition of
\f4waitpid\f1
and the
.SM IRIX
implementation of
\f4sigaction\f1
solves both of these problems.
Note that neither the
.SM BSD
nor the System V signal routines on
.SM IRIX
have these properties,
in the interests of compatibility.
.PP
.SM WARNING:
programs that install
.B \s-1SIGCLD\s0
handlers that set flags instead of executing \f4waitpid\fPs and then
attempt to restore the previous signal handler (via \f4sigaction\fP)
upon return from the handler will create infinite loops.
.PP
.Ex
/*
* POSIX example of waitpid-in-SIGCHLD handler usage
*/
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
static void handler(int);
#define NUMKIDS 4
volatile int kids = NUMKIDS;
/*
* If waitpid's 1st argument is -1, it waits for any child.
*/
#define ANYKID -1
main()
{
int i;
pid_t pid;
struct sigaction act;
sigset_t set, emptyset;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGCHLD);
act.sa_flags = 0;
sigaction(SIGCHLD, &act, NULL);
sigemptyset(&set);
sigemptyset(&emptyset);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, NULL);
setbuf(stdout, NULL);
for (i = 0; i < NUMKIDS; i++) {
if (fork() == 0) {
printf("Child %d\en", getpid());
exit(0);
}
}
while (kids > 0) {
sigsuspend(&emptyset);
}
}
static void
handler(int sig)
{
pid_t pid;
int status;
printf("Parent (%d) in handler, ", getpid());
pid = waitpid(ANYKID, &status, WNOHANG);
while (pid > 0) {
kids--;
printf("child %d, now %d left\en", pid, kids);
pid = waitpid(ANYKID, &status, WNOHANG);
}
}
.Ee
.Op
.SH DIAGNOSTICS
\f4wait\f1
fails and its actions are undefined if
\f2statptr\f1
points to an invalid address.
If
\f4wait\f1,
\f4wait3\f1,
or
\f4waitpid\f1
return due to a stopped
or terminated child process, the process
.SM ID
of the child is returned to the calling process.
\f4wait3\f1
and
\f4waitpid\f1
return 0 if
.SM
.B WNOHANG
is specified and there are currently no stopped
or exited children (although children
.SM DO
exist).
Otherwise, a value of \-1
is returned and \f2errno\fP is set to indicate the error:
.TP 15
.SM
\%[EINTR]
The calling process received a signal.
.TP 15
.SM
\%[ECHILD]
The calling process has no existing unwaited-for child processes.
.TP 15
.SM
\%[ECHILD]
The process or process group specified by
\f2pid\f1
does not exist or is not a child of the calling process (\f4waitpid\f1 only).
.TP 15
.SM
\%[EFAULT]
The \f2rusage\fP or \f2statptr\fP arguments (where applicable) point to
illegal addresses.
.TP 15
.SM
\%[EINVAL]
The value of the
\f2options\f1
argument is not valid (\f4waitpid\f1 and \f4wait3\f1 only).
.\" @(#)wait.2 6.2 of 9/6/83
.SH "SEE ALSO"
exec(2), exit(2), fork(2), intro(2), pause(2), ptrace(2), signal(2),
sigset(2), sigpause(2), sigaction(2), sigsuspend(2), sigprocmask(2),
signal(3B), sigvec(3B), sigpause(3B), wait(3b), getrusage(3), wstat(5).
.Op c p a
.SH NOTE
Currently,
\f4wait3\f1
returns zero for the
.I ru_ixrss, ru_idrss
and
.I ru_isrss
fields in
.IR rusage .
.Op