waitpid() — Wait for a specific child process to end

Standards

Standards / Extensions C or C++ Dependencies
POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3
both  

Format

#define _POSIX_SOURCE
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status_ptr, int options);

General description

Suspends the calling process until a child process ends or is stopped. More precisely, waitpid() suspends the calling process until the system gets status information on the child. If the system already has status information on an appropriate child when waitpid() is called, waitpid() returns immediately. waitpid() is also ended if the calling process receives a signal whose action is either to execute a signal handler or to end the process.
pid_t pid
Specifies the child processes the caller wants to wait for:
  • If pid is greater than 0, waitpid() waits for termination of the specific child whose process ID is equal to pid.
  • If pid is equal to zero, waitpid() waits for termination of any child whose process group ID is equal to that of the caller.
  • If pid is -1, waitpid() waits for any child process to end.
  • If pid is less than -1, waitpid() waits for the termination of any child whose process group ID is equal to the absolute value of pid.
int *status_ptr
Points to a location where waitpid() can store a status value. This status value is zero if the child process explicitly returns zero status. Otherwise, it is a value that can be analyzed with the status analysis macros described in “Status Analysis Macros”, below.

The status_ptr pointer may also be NULL, in which case waitpid() ignores the child's return status.

int options
Specifies additional information for waitpid(). The options value is constructed from the bitwise inclusive-OR of zero or more of the following flags defined in the sys/wait.h header file:
WCONTINUED
Special behavior for XPG4.2: Reports the status of any continued child processes as well as terminated ones. The WIFCONTINUED macro lets a process distinguish between a continued process and a terminated one.
WNOHANG
Demands status information immediately. If status information is immediately available on an appropriate child process, waitpid() returns this information. Otherwise, waitpid() returns immediately with an error code indicating that the information was not available. In other words, WNOHANG checks child processes without causing the caller to be suspended.
WUNTRACED
Reports on stopped child processes as well as terminated ones. The WIFSTOPPED macro lets a process distinguish between a stopped process and a terminated one.

Special behavior for XPG4.2: If the calling process has SA_NOCLDWAIT set or has SIGCHLD set to SIG_IGN, and the process has no unwaited for children that were transformed into zombie processes, it will block until all of the children terminate, and waitpid() will fail and set errno to ECHILD.

Status analysis macros: If the status_ptr argument is not NULL, waitpid() places the child's return status in *status_ptr. You can analyze this return status with the following macros, defined in the sys/wait.h header file:
WEXITSTATUS(*status_ptr)
When WIFEXITED() is nonzero, WEXITSTATUS() evaluates to the low-order 8 bits of the status argument that the child passed to the exit() or _exit() function, or the value the child process returned from main().
WIFCONTINUED(*status_ptr)
Special behavior for XPG4.2: This macro evaluates to a nonzero (true) value if the child process has continued from a job control stop. This should only be used after a waitpid() with the WCONTINUED option.
WIFEXITED(*status_ptr)
This macro evaluates to a nonzero (true) value if the child process ended normally (that is, if it returned from main(), or else called the exit() or _exit() function).
WIFSIGNALED(*status_ptr)
This macro evaluates to a nonzero (true) value if the child process ended because of a signal that was not caught.
WIFSTOPPED(*status_ptr)
This macro evaluates to a nonzero (true) value if the child process is currently stopped. This should only be used after a waitpid() with the WUNTRACED option.
WSTOPSIG(*status_ptr)
When WIFSTOPPED() is nonzero, WSTOPSIG() evaluates to the number of the signal that stopped the child.
WTERMSIG(*status_ptr)
When WIFSIGNALED() is nonzero, WTERMSIG() evaluates to the number of the signal that ended the child process.

Returned value

If successful, waitpid() returns a value of the process (usually a child) whose status information has been obtained.

If WNOHANG was given, and if there is at least one process (usually a child) whose status information is not available, waitpid() returns 0.

If unsuccessful, waitpid() returns -1 and sets errno to one of the following values:
Error Code
Description
ECHILD
The process specified by pid does not exist or is not a child of the calling process, or the process group specified by pid does not exist or does not have any member process that is a child of the calling process.
EINTR
waitpid() was interrupted by a signal. The value of *status_ptr is undefined.
EINVAL
The value of options is incorrect.

Example

CELEBW02
/* CELEBW02

   The following function suspends the calling process using &waitpid.
   until a child process ends.

 */
#define _POSIX_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>

main() {
  pid_t pid;
  time_t t;
  int status;

  if ((pid = fork()) < 0)
    perror("fork() error");
  else if (pid == 0) {
    sleep(5);
    exit(1);
  }
  else do {
    if ((pid = waitpid(pid, &status, WNOHANG)) == -1)
      perror("wait() error");
    else if (pid == 0) {
      time(&t);
      printf("child is still running at %s", ctime(&t));
      sleep(1);
    }
    else {
      if (WIFEXITED(status))
        printf("child exited with status of %d\n", WEXITSTATUS(status));
      else puts("child did not exit successfully");
    }
  } while (pid == 0);
}
Output:
child is still running at Fri Jun 16 11:05:43 2006
child is still running at Fri Jun 16 11:05:44 2006
child is still running at Fri Jun 16 11:05:45 2006
child is still running at Fri Jun 16 11:05:46 2006
child is still running at Fri Jun 16 11:05:47 2006
child is still running at Fri Jun 16 11:05:48 2006
child is still running at Fri Jun 16 11:05:49 2006
child exited with status of 1

Related information