Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should we check WIFEXITED after wait in order to kill child processes in Linux system call?

I came across some code in C where we check the return value of wait and if it's not an error there's yet another check of WIFEXITED and WIFEXITSTATUS. Why isn't this redundant? As far as I understand wait returns -1 if an error occurred while WIFEXITED returns non-zero value if wait child terminated normally. So if there wasn't any error in this line if ( wait(&status) < 0 ) why would anything go wrong durng WIFEXITED check?

This is the code:

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

#define CHILDREN_NUM 5

int main () {

    int i, status, pid, p;
    for(i = 0; (( pid = fork() ) < 0) && i < CHILDREN_NUM;i++)
        sleep(5);


    if ( pid == 0 )
    {
        printf(" Child %d : successfully created!\n",i);
        exit( 0 );  /* Son normally exits here! */
    }

    p = CHILDREN_NUM;
    /* The father waits for agents to return succesfully */
    while ( p >= 1 )
    {
        if ( wait(&status) < 0 ) {
            perror("Error");
            exit(1);
        }

        if ( ! (WIFEXITED(status) && (WEXITSTATUS(status) == 0)) )  /* kill all running agents */
        {
            fprintf( stderr,"Child failed. Killing all running children.\n");
           //some code to kill children here
            exit(1);
        }
        p--;
    }

    return(0);
}
like image 468
Yos Avatar asked Nov 22 '17 18:11

Yos


People also ask

What does Wifexited do?

WIFEXITED and WEXITSTATUS are two of the options which can be used to know the exit status of the child. WIFEXITED(status) : returns true if the child terminated normally. WEXITSTATUS(status) : returns the exit status of the child.

What happens if a process that has no children calls wait Null?

If any process has no child process then wait() returns immediately “-1”.

What is the purpose of wait ()?

The wait() function will suspend execution of the calling thread until status information for one of its terminated child processes is available, or until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process.


1 Answers

wait returning >= 0 tells you a child process has terminated (and that calling wait didn't fail), but it does not tell you whether that process terminated successfully or not (or if it was signalled).

But, here, looking at your code, it's fairly obvious the program does care about whether the child process that terminated did so successfully or not:

fprintf( stderr,"Child failed. Killing all running children.\n");

So, the program needs to do further tests on the status structure that was populated by wait:

  • WIFEXITED(status): did the process exit normally? (as opposed to being signalled).
  • WEXITSTATUS(status) == 0: did the process exit with exit code 0 (aka "success"). For more information, see: Meaning of exit status 1 returned by linux command.
like image 57
Thomas Orozco Avatar answered Oct 03 '22 23:10

Thomas Orozco