In this chapter we shall learn about:
1. Linux Process wait() system call
2. waitpid()
3. wait()
4. Process Completion Status:
5. Example 1: Simple wait system call:
6.Example 2: wait system call, when child generates segmentation fault
Linux Process wait() system call
We know the below points:
1. “fork()” system call is used to create a new child process.
2. You can replace the child process image with the help of execl system calls.
3. “fork()” will return 0 to child process and returns the process ID of child to parent process. If there is an error in creating a child process “-1” will be returned.
4. So when a child process is created, then the parent process should be put to sleep until a child process is completed.
“wait()” system call is used to block the calling process until one of its child exits or a signal is received.
Below are the header files to be included:
#include <sys/types.h> #include <sys/wait.h>
There are 2 variants of wait system call:
wait and waitpid.
1. waitpid
Function prototype: pid_t waitpid (pid_t pid, int *status-ptr, int options)
This variant is used, when the parent process wants to wait for a particular child process to complete, the child process id to be waited is passed in “pid” argument.
If -1 or WAIT_ANY is sent in “pid”, then it will wait for any child process.
The status information of a particular child process can be got by status-ptr argument. If you send a NULL pointer, no status will be updated.
“options” argument is a bit mask. The value should be a bitwise OR of zero or more WNOHANG and WUNTRACED flags.
WNOHANG: This flag specifies that waitpid should return immediately instead of waiting, if there is no child process ready to be noticed.
WUNTRACED: This flag specifies that waitpid should report the status of any child processes that have been stopped as well as those that have terminated.
2. wait
Function prototype: pid_t wait (int *status-ptr)
It is a simplified version of waitpid().
It is exactly equivalent to “waitpid (-1, &status, 0)”.
Process Completion Status:
This exit status will be filled in the “status-ptr” argument. Below are some of the possible values:
WIFEXITED: Returns a nonzero value if the child process terminated normally with exit or _exit.
WIFSIGNALED: Returns a nonzero value if the child process terminated due to a signal that was not caught.
WCOREDUMP: Returns a nonzero value if the child process terminated due to a signal that was not caught and caused core dump.
WIFSTOPPED: Returns a nonzero value if the child process is currently stopped.
So by reading the above statements related to waitpid and wait system call, the parent process should keep checking the status of the child process in a while loop, if the child process takes longer time to execute.
Below is the simple example for wait system call:
#include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int i, j, status; i = fork(); if (i > 0) { j = wait(&status); printf("In Parent\n"); printf(" Return value: %d\n", j); printf(" Status: %d\n", status); printf(" WIFSTOPPED: %d\n", WIFSTOPPED(status)); printf(" WIFSIGNALED: %d\n", WIFSIGNALED(status)); printf(" WIFEXITED: %d\n", WIFEXITED(status)); printf(" WEXITSTATUS: %d\n", WEXITSTATUS(status)); printf(" WTERMSIG: %d\n", WTERMSIG(status)); printf(" WSTOPSIG: %d\n", WSTOPSIG(status)); } else { printf("Child PID (%d)\n", getpid()); exit(0); } }
Output:
Child PID (86479) In Parent Return value: 86479 Status: 0 WIFSTOPPED: 0 WIFSIGNALED: 0 WIFEXITED: 1 WEXITSTATUS: 0 WTERMSIG: 0 WSTOPSIG: 0
Below is the simple example for wait system call, child generates segmentation fault :
#include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int i, j, status; char *cPtr; i = fork(); if (i > 0) { j = wait(&status); printf("In Parent\n"); printf(" Return value: %d\n", j); printf(" Status: %d\n", status); printf(" WIFSTOPPED: %d\n", WIFSTOPPED(status)); printf(" WIFSIGNALED: %d\n", WIFSIGNALED(status)); printf(" WIFEXITED: %d\n", WIFEXITED(status)); printf(" WEXITSTATUS: %d\n", WEXITSTATUS(status)); printf(" WTERMSIG: %d\n", WTERMSIG(status)); printf(" WSTOPSIG: %d\n", WSTOPSIG(status)); } else { printf("Child (%d) generating a seg fault\n", getpid()); cPtr = NULL; *cPtr = 'a'; } return 0; }
Output:
Child (86692) generating a seg fault In Parent Return value: 86692 Status: 11 WIFSTOPPED: 0 WIFSIGNALED: 1 WIFEXITED: 0 WEXITSTATUS: 0 WTERMSIG: 11 WSTOPSIG: 0