Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fork/exec/waitpid issue

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

   }
}
like image 969
Jim Ruffian Avatar asked Dec 06 '12 01:12

Jim Ruffian


People also ask

Is Waitpid a blocking call?

It is a blocking call that will wait till any of the child processes terminates. There are other options as well. Using the waitpid function you could wait for a specific child to terminate using its PID or you can have a non-blocking way to check if there is any child-processes that has already terminated.

How do I call Waitpid in a non-blocking manner?

The WNOHANG flag (set in the options argument) will make the call to waitpid() non-blocking. You'll have to call it periodically to check if the child is finished yet. Or you could setup SIGCHLD to take care of the children.

How does Waitpid work?

Specifies the child processes the caller wants to wait for: If pid is greater than 0, waitpid() waits for termination of the specific child whose process ID is equal to pid. If pid is equal to zero, waitpid() waits for termination of any child whose process group ID is equal to that of the caller.

How do I write Waitpid?

Syntax of waitpid() : pid_t waitpid(pid_t pid, int *status, int options); The value of pid can be: < -1: Wait for any child process whose process group ID is equal to the absolute value of pid .


1 Answers

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! */
}
like image 144
William Pursell Avatar answered Sep 25 '22 16:09

William Pursell