fork/exec/waitpid issue

Jim Ruffian picture Jim Ruffian · Dec 6, 2012 · Viewed 9.3k times · Source

I'm trying to determine whether an execution failed by checking the result of waitpid(). However, even when I run a command that I know fails and writes the issue to stderr, the check below never registers. What could possibly be wrong with this code?

Thanks for any help.

pid_t pid;  // the child process that the execution runs inside of.
int ret;      // exit status of child process.

child = fork();

if (pid == -1)
{
   // issue with forking
}
else if (pid == 0)
{
   execvp(thingToRun, ThingToRunArray); // thingToRun is the program name, ThingToRunArray is
                                        //    programName + input params to it + NULL.

   exit(-1);
}
else // We're in the parent process.
{
   if (waitpid(pid, &ret, 0) == -1)
   {
      // Log an error.
   }

   if (!WIFEXITED(ret)) // If there was an error with the child process.
   {

   }
}

Answer

William Pursell picture William Pursell · Dec 6, 2012

waitpid only returns -1 if an error occurs with waitpid. That is, if you give it an incorrect pid, or it is interrupted, etc. If the child has a failing exit status, waitpid will succeed (return the pid) and set ret to reflect the status of the child.

To determine the status of the child, use WIFEXITED(ret) and WEXITSTATUS(ret). For example:

if( waitpid( pid, &ret, 0 ) == -1 ) {
  perror( "waitpid" );
} else if( WIFEXITED( ret ) && WEXITSTATUS( ret ) != 0 ) {
    ; /* The child failed! */
}