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);
}
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.
If any process has no child process then wait() returns immediately “-1”.
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.
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With