Search code examples
clinuxforkwaitwaitpid

Which one to choose waitpid/wait/waitid?


I want to use execl in child process after doing fork. execl will execute the script which will take around 120 seconds of time. I tried almost all the combination with waitpid, wait and waitid with different argument (0, WNOHANG, etc.,) but in all case I am getting -1 return value. So I want to know in which wait function I need to use when? So I can concentrate in one wait function to make it work.

One more interesting thing which I observed from my logs is that when I am doing nothing in child process it is showing my parent thread as orphaned. I don't know how it is possible? How can my parent thread become orphaned?

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

int main(void)
{
    pid_t Checksum_pid = fork();

    if (Checksum_pid < 0)
        printf("Fork Failed\n");
    else if (Checksum_pid == 0)
    {
        execl("/bin/ls","ls",(char *)NULL) ;
        exit(EXIT_FAILURE);
    }
    else
    {
        int childStatus;
        pid_t returnValue = waitpid(Checksum_pid, &childStatus, 0);

        if (returnValue > 0)
        {
            if (WIFEXITED(childStatus))
                printf("Exit Code: %d\n", WEXITSTATUS(childStatus));

        }
        else if (returnValue == 0)
            printf("Child process still running\n");
        else
        {
            if (errno == ECHILD)
                printf(" Error ECHILD!!\n");
            else if (errno == EINTR)
                printf(" Error EINTR!!\n");
            else
                printf("Error EINVAL!!\n");
        }
    }

    return 0;
}

Solution

  • As I commented: your last else should just be

     else perror("waitpid");
    

    But you are getting ECHILD. So please read waitpid(2) man page:

       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.)
    

    BTW, I cannot reproduce your error. Check also your limits as given by ulimit -a on bash.

    Maybe your execl fails (especially if you execute some script instead of /bin/ls). Add a call to perror after it.

    Also, compile with gcc -Wall -g and use strace and gdb