Why is waitpid(-1, &status, 0) not suspending the process without any childs at all?

3.1k views Asked by At

I don't understand the waitpid() function very well. The manual says:

The wait() system call suspends execution of the calling process until one of its children terminates. The call wait(&status) is equivalent to: waitpid(-1, &status, 0);

Source: http://manpages.ubuntu.com/manpages/raring/man2/wait.2.html

As far as I understand this: If I have a process and no child process what so ever and call the waitpid(-1, &status, 0) function then the process should hang there and don't continue because there can never be a state change without children and so the process just hangs there waiting for the child process to change state which will never happen in this case, but this understanding seems to be wrong because the code below does not hang at the waitpid() function. Instead it returns -1 for error which is plausible because there was no child process whatsoever but as my understanding according to the manual goes the program should just hang at/in the waitpid() function and wait for a child to change state. Yet there is no child, so there is no status change, so it should just hang in the waitpid() function and wait and wait. The below code should never reach the printf() statement but instead it does reach the printf() function.

This code is just for demonstrations puposes:

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

int main() {
  int status;
  pid_t pid;
  pid = waitpid(-1, &status, 0);
  printf("%i\n", (int) pid); // pid returns -1
  return 0;
}

This program executes until the end but to my understanding according to the manual it shouldn't. What's wrong with my above reasoning?

2

There are 2 answers

2
Scott Hunter On BEST ANSWER

Clearly, the intention is that, by returning -1, it is indicating that there are no children to wait for (in a sense, all children have terminated).

1
Oswald On

Check errno to find out why waitpid returned -1:

ECHILD (for wait()) The calling process does not have any unwaited-for children.

ECHILD (for waitpid() or waitid()) The process specified by pid (waitpid()) or idtype and id (waitid()) does not exist or is not a child of the calling process. (This can happen for one's own child if the action for SIGCHLD is set to SIG_IGN. See also the Linux Notes section about threads.)

EINTR WNOHANG was not set and an unblocked signal or a SIGCHLD was caught; see signal(7).

EINVAL The options argument was invalid.