waitpid -- Wait for a Specific Process to End

SYNOPSIS

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

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

DESCRIPTION

waitpid suspends the calling process until a specified process terminates. When the specified process ends, status information from the terminating process is stored in the location pointed to by statusPtr and the calling process resumes execution. If the specified process has already ended when the waitpid function is called and the system has status information, the return from waitpid occurs immediately. A return from the waitpid function also occurs if a signal is received and is not ignored.
pid
specifies a process, normally a child process, that the calling process waits for. The process is identified as follows:
If pid is greater than 0, the calling process waits for the process whose process identification number (PID) is equal to the value specified by pid.
If pid is equal to 0, the calling process waits for the process whose process group ID is equal to the PID of the calling process.
If pid is equal to -1, the calling process waits for any child process to terminate.
If pid is less than -1, the calling process waits for the process whose process group ID is equal to the absolute value of pid.
statusPtr
is a pointer to the location where status information for the terminating process is to be stored. There is one situation when status information is not available after a call to waitpid: if waitpid is called with NULL as the statusPrt value, no status information is returned. Assuming that this situation does not apply, the macros described in Analyzing Status Information are used to analyze the status information.
options
specifies optional actions for the waitpid function. Either of the following option flags may be specified, or they can be combined with a bitwise inclusive OR operator:
WNOHANG
causes the call to waitpid to return status information immediately, without waiting for the specified process to terminate. Normally, a call to waitpid causes the calling process to be blocked until status information from the specified process is available; the WNOHANG option prevents the calling process from being blocked. If status information is not available, waitpid returns a 0.
WUNTRACED
causes the call to waitpid to return status information for a specified process that has either stopped or terminated. Normally, status information is returned only for terminated processes.

Analyzing Status Information

After the call to waitpid, status information stored at the location pointed to by statusPtr can be evaluated with the following macros:
WIFEXITED(*statusPtr)
evaluates to a nonzero (true) value if the specified process terminated normally.
WEXITSTATUS(*statusPtr)
if the specified process terminated normally, this macro evaluates the lower 8 bits of the value passed to the exit or _exit function or returned from main.
WIFSIGNALED(*statusPtr)
evaluates to a nonzero (true) value if the specified process terminated because of an unhandled signal.
WTERMSIG(*statusPtr)
if the specified process is ended by an unhandled signal, this macro evaluates to the number of that signal.
WIFSTIPPED(*statusPtr)
evaluates to a nonzero (true) value if the specified process is currently stopped but not terminated.
WSTOPSIG(*statusPtr)
if the specified process is currently stopped but not terminated, then this macro evaluates to the number of the signal that caused the process to stop

RETURN VALUE

If successful, waitpid returns the process ID of the terminated process whose status was reported. If unsuccessful, a -1 is returned.

CAUTIONS

If W_NOHANG is not specified, the waitpid function will terminate if a signal managed by OpenEdition arrives before any child process has terminated. It will not terminate if a signal managed by SAS/C arrives; the signal will remain pending until the completion of waitpid.

PORTABILITY

The waitpid function is defined by the POSIX.1 standard.

Older UNIX programs may manipulate the status information stored at the location pointed to by statusPtr directly. These programs must be changed to use the POSIX.1 defined macros. This is necessary because OpenEdition and SAS/C use different values for signal numbers, and the status codes reflect OpenEdition signal numbers, not SAS/C signal numbers. For instance, a process terminated with the SIGKILL signal will have status code 9, but the comparison (status == SIGKILL) will fail. A correct POSIX-conforming test for process termination by SIGKILL would be as follows:

 (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
 
The WTERMSIG macro performs conversion of OpenEdition signal numbers to SAS/C signal numbers.

EXAMPLE

The following example illustrates the use of waitpid to wait for a process to end:
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <unistd.h>
  #include <time.h>
  #include <stdio.h>
  #include <stdlib.h>

  int main(void)
  {
     int i, status;
     pid_t childID, endID;
     time_t when;

     if ((childID = fork()) == -1) {     /* Start a child process.      */
        perror("fork error");
        exit(EXIT_FAILURE);
     }
     else if (childID == 0) {            /* This is the child.          */
        time(&when);
        printf("Child process started at %s", ctime(&when));
        sleep(10);                       /* Sleep for 10 seconds.       */
        exit(EXIT_SUCCESS);
     }
     else {                              /* This is the parent.         */
        time(&when);
        printf("Parent process started at %s", ctime(&when));

           /* Wait 15 seconds for child process to terminate.           */
        for(i = 0; i < 15; i++) {
           endID = waitpid(childID, &status, WNOHANG|WUNTRACED);
           if (endID == -1) {            /* error calling waitpid       */
              perror("waitpid error");
              exit(EXIT_FAILURE);
           }
           else if (endID == 0) {        /* child still running         */
              time(&when);
              printf("Parent waiting for child at %s", ctime(&when));
              sleep(1);
           }
           else if (endID == childID) {  /* child ended                 */
              if (WIFEXITED(status))
                 printf("Child ended normally.n");
              else if (WIFSIGNALED(status))
                 printf("Child ended because of an uncaught signal.n");
              else if (WIFSTOPPED(status))
                 printf("Child process has stopped.n");
              exit(EXIT_SUCCESS);
           }
        }
     }
  }

 

RELATED FUNCTIONS

fork, wait


Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.