*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->IRIX man pages -> standard/wait (2)              
Title
Content
Arch
Section
 

Contents


WAIT(2)								       WAIT(2)


NAME    [Toc]    [Back]

     wait, waitpid, wait3 - wait for child processes to	stop or	terminate

C SYNOPSIS    [Toc]    [Back]

     #include <sys/types.h>
     #include <sys/wait.h>

     pid_t wait	(int *statptr);
     pid_t waitpid (pid_t pid, int *statptr, int options);

     #include <sys/types.h>
     #include <sys/wait.h>
     #include <sys/resource.h>

     pid_t wait3 (int *statptr,	int options, struct rusage *rusage);

DESCRIPTION    [Toc]    [Back]

     wait 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	wait will return prematurely if	a signal is
     received.	If all child processes stopped or terminated prior to the call
     on	wait, return is	immediate.

     If	the call is successful,	the process ID of a child is returned.

     wait3 is BSD's extension of wait.	It provides an alternate interface for
     programs that must	not block when collecting the status of	child
     processes.

     waitpid is	POSIX's	extension of wait.  The	pid argument specifies a set
     of	child processes	for which status is requested.	waitpid	only returns
     the status	of a child process from	this set.

PARAMETERS    [Toc]    [Back]

     statptr (all functions): If statptr is non-zero, 16 bits of information
     called status are stored in the low-order 16 bits of the location pointed
     to	by statptr.  Status may	be evaluated with the macros described on
     wstat(5).	Status can be used to differentiate between stopped and
     terminated	child processes. If the	child process terminated, status
     identifies	the cause of termination and passes useful information to the
     parent.  status is	interpreted as follows:

	  If the child process stopped,	the predicate WIFSTOPPED(*statptr)
	  will evaluate	to non-zero and	WSTOPSIG(*statptr) will	return the
	  signal number	that caused the	process	to stop.  (The high-order 8
	  bits of status will contain the signal number	and the	low-order 8
	  bits are set equal to	WSTOPFLG.)

	  If the child process terminated due to an exit call, the predicate
	  WIFEXITED(*statptr) will evaluate to non-zero, and
	  WEXITSTATUS(*statptr)	will return the	argument that the child
	  process passed to _exit or exit, or the value	the child process



									Page 1






WAIT(2)								       WAIT(2)



	  returned from	main [see exit(2)].  (The low-order 8 bits of status
	  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	exit.)

	  If the child process terminated due to a signal, the predicate
	  WIFSIGNALED(*statptr)	will evaluate to non-zero, and
	  WTERMSIG(*statptr) will return the signal number that	caused the
	  termination.	(The high-order	8 bits of status will be zero and the
	  low-order 8 bits will	contain	the number of the signal.)  In
	  addition, if WCOREFLG	is set,	a ``core image'' will have been
	  produced [see	signal(2)].

     rusage (wait3): If	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).

     pid (waitpid):

	  1) If	pid is equal to	-1, status is requested	for any	child process.
	  In this respect, waitpid is then equivalent to wait.

	  2) If	pid is greater than zero, it specifies the process ID of a
	  single child process for which status	is requested.

	  3) If	pid is equal to	zero, status is	requested for any child
	  process whose	process	group ID is equal to that of the calling
	  process.

	  4) If	pid is less than -1, status is requested for any child process
	  whose	process	group ID is equal to the absolute value	of pid.

     options (waitpid and wait3): The options argument is constructed from the
     bitwise inclusive OR of zero or more of the following flags, defined in
     the header	<sys/wait.h>:

     WNOHANG	    The	function will not suspend execution of the calling
		    process if status is not immediately available for one of
		    the	child processes.

     WUNTRACED	    The	status of child	processes that are stopped due to a
		    SIGTTIN, SIGTTOU, SIGTSTP, or SIGSTOP signal, and whose
		    status has not yet been reported since they	stopped, are
		    reported to	the requesting process.

     If	a parent process terminates without waiting for	its child processes to
     terminate,	the parent process ID of each child process is set to 1.  This
     means the initialization process inherits the child processes [see
     intro(2)].







									Page 2






WAIT(2)								       WAIT(2)



SIGCLD HANDLING
     IRIX has three distinct version of	signal routines: System	V (signal(2)
     and sigset(2)), 4.3BSD (signal(3B)	and sigvec(3B)), and POSIX
     (sigaction(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
     SIGCLD 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.

     Note that System V	refers to this signal as SIGCLD, whereas BSD calls it
     SIGCHLD.  For compatibility with both systems they	are defined to be the
     same signal number, and may therefore be used interchangeably.

     System V: System V's SIGCLD mechanism guarantees that no SIGCLD signals
     will be lost.  It accomplishes this by forcing the	process	to reinstall
     the handler (via signal or	sigset calls) when leaving the handler.	 Note
     that whereas signal(2) sets the signal disposition	back to	SIG_DFL	each
     time the handler is called, sigset(2) keeps it installed, so SIGCLD 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.  The code	below is the System V example.	Note that the
     sigpause(2) creates a window during which SIGCLD is not blocked, allowing
     the parent	to enter its handler.

	  /*
	   * 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\n",	getpid());
		   exit(0);
	       }
	      }
	      while (kids > 0) {
	       sigpause(SIGCLD);



									Page 3






WAIT(2)								       WAIT(2)



	      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\n",	pid, kids);
	      /*
	       * Now reinstall handler & cause SIGCLD to be re-raised
	       * if any	more children exited while we were in here.
	       */
	      sigset(SIGCLD, handler);
	  }


     BSD: 4.3BSD solved	this problem differently: instead of guaranteeing that
     no	SIGCHLD	signals	are lost, it provides a	WNOHANG	option to wait3	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 SIGCHLD signals arrived while the parent was in its
     handler, the signal will remain pending, the parent will reenter the
     handler, and the wait3 call will return 0.	 Note that it is not necessary
     to	call sigvec upon exit from the handler.

	  /*
	   * 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;



									Page 4






WAIT(2)								       WAIT(2)



	      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\n",	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\n", pid, kids);
	      }
	  }


     POSIX: POSIX improved on the BSD method by	providing waitpid, that	allows
     a parent to wait on a particular child process if desired.	 In addition,
     the IRIX implementation of	sigaction(2) checks for	zombied	children upon
     exit from the system call if the specified	signal was SIGCLD and the
     disposition of the	signal handling	was changed.  If zombied children
     exist, another SIGCLD 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 system(3)) creates and waits on its own
     children.

     Two problems have classically arisen in such a scheme: 1) until the
     advent of waitpid,	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	SIGCLD 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 SIGCLD handler would reap and	discard	those
     children.	The addition of	waitpid	and the	IRIX implementation of
     sigaction solves both of these problems.  Note that neither the BSD nor
     the System	V signal routines on IRIX have these properties, in the
     interests of compatibility.



									Page 5






WAIT(2)								       WAIT(2)



     WARNING:  programs	that install SIGCLD handlers that set flags instead of
     executing waitpids	and then attempt to restore the	previous signal
     handler (via sigaction) upon return from the handler will create infinite
     loops.

	  /*
	  * 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\n",	getpid());
		   exit(0);
	       }
	      }
	      while (kids > 0) {
	       sigsuspend(&emptyset);
	      }
	  }



									Page 6






WAIT(2)								       WAIT(2)



	  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\n", pid, kids);
	       pid = waitpid(ANYKID, &status, WNOHANG);
	      }
	  }

DIAGNOSTICS    [Toc]    [Back]

     wait fails	and its	actions	are undefined if statptr points	to an invalid
     address.  If wait,	wait3, or waitpid return due to	a stopped or
     terminated	child process, the process ID of the child is returned to the
     calling process.  wait3 and waitpid return	0 if WNOHANG is	specified and
     there are currently no stopped or exited children (although children DO
     exist).  Otherwise, a value of -1 is returned and errno is	set to
     indicate the error:

     [EINTR]	    The	calling	process	received a signal.

     [ECHILD]	    The	calling	process	has no existing	unwaited-for child
		    processes.

     [ECHILD]	    The	process	or process group specified by pid does not
		    exist or is	not a child of the calling process (waitpid
		    only).

     [EFAULT]	    The	rusage or statptr arguments (where applicable) point
		    to illegal addresses.

     [EINVAL]	    The	value of the options argument is not valid (waitpid
		    and	wait3 only).

SEE ALSO    [Toc]    [Back]

      
      
     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).

NOTE    [Toc]    [Back]

     Currently,	wait3 returns zero for the ru_ixrss, ru_idrss and ru_isrss
     fields in rusage.


									PPPPaaaaggggeeee 7777
[ Back ]
 Similar pages
Name OS Title
wait4 Tru64 Wait for a child process to stop or terminate
waitpid HP-UX wait for child process to stop or terminate
wait3 Tru64 Wait for a child process to stop or terminate
wait HP-UX wait for child process to stop or terminate
wait Tru64 Wait for a child process to stop or terminate
waitpid Tru64 Wait for a child process to stop or terminate
powerdown IRIX stop all processes and halt the system
waitid HP-UX wait for child process to change state
waitid Tru64 Wait for child process to change state
waitid IRIX wait for child process to change state
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service