Link to home
Start Free TrialLog in
Avatar of zagzag
zagzag

asked on

Understanding the behaviour of waitpid(-1, NULL, WNOHANG)

As far as I understand from waitpid's man page, when calling waitpid with WNOHANG, the function should return 0 if there are no child processes to wait for.
When running the following program -

===
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define N 5

void error_exit(char *str)
{
      perror(str);
      exit(1);
}

void sigchld_handler(int sig)
{
      pid_t      pid;
      do {
            pid = waitpid(-1, NULL, WNOHANG);
            printf("child %d\n",pid);
      } while ( pid > 0 );
      
      if ( errno == ECHILD )
            puts("errno=ECHILD");
      if ( pid < 0 )
            error_exit("waitpid");

      if ( signal(SIGCHLD, sigchld_handler) == SIG_ERR )
            error_exit("signal");
}

int main()
{
      int       i;
      pid_t       pid;
      
      if ( signal(SIGCHLD, sigchld_handler) == SIG_ERR )
            error_exit("signal");
      
      for ( i = 0; i < N; i += 1 ) {
            pid = fork();
            if ( pid < 0 )
                  // fork error
                  error_exit("fork");
            else if ( pid == 0 ) {
                  // child process - sleep
                  sleep(N-i+1);
                  exit(0);
            }
      }
      while(1);
      
      return 0;
}
===

I get this output -

===
child 5398
child 0
child 5397
child 0
child 5396
child 0
child 5395
child 0
child 5394
child -1
errno=ECHILD
waitpid: No child processes
===

As you can see, after all child processes have been "collected", waitpid returns -1 (which means an error occured) and sets errno to ECHILD. I'd like to know why do I get this error, and what is the problem with my code.

TIA

Edit:
My kernel version is 2.6.4 (also tried 2.4.22), and my GCC version is 3.3.3 (also tried 3.2.3).
Avatar of Karl Heinz Kremer
Karl Heinz Kremer
Flag of United States of America image

Your interpretation of the man page is not quite right:

      WNOHANG
              which  means  to return immediately if no child has
              exited.

If you start a bunch of child processes, but none of them has exited, waitpid will return right away if you specify WNOHANG. Your system is therefore doing the right thing by reporting "no child process".
ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of zagzag
zagzag

ASKER

Thanks :)