Handling errors from execvp()

Kvass picture Kvass · Nov 19, 2013 · Viewed 21.1k times · Source

I am a little confused about how to handle errors from execvp(). My code so far looks like this:

int pid = fork();
if (pid < 0) {
    // handle error.
}
else if (pid == 0) {
    int status = execvp(myCommand,myArgumentVector); // status should be -1 because execvp
                                                     // only returns when an error occurs
    // We only reach this point as a result of failure from execvp
    exit(/* What goes here? */);
}
else {
    int status;
    int waitedForPid = waitpid(pid,&status,0);
    //...
}

There are three cases I'm trying to address:

  1. myCommand,myArgumentVector are valid and the command executes correctly.
  2. myCommand,myArgumentVector are valid parameters, but something goes wrong in the execution of myCommand.
  3. myCommand,myArgumentVector are invalid parameters (e.g. myCommand cannot be found) and the execvp() call fails.

My primary concern is that the parent process will have all the information it needs in order to handle the child's error correctly, and I'm not entirely sure how to do that.

In the first case, the program presumably ended with an exit status of 0. This means that if I were to call WIFEXITED(status) in the macro, I should get true. I think this should work fine.

In the second case, the program presumably ended with an exit status other than 0. This means that if I were to call WEXITSTATUS(status) I should get the specific exit status of the child invocation of myCommand (please advise if this is incorrect).

The third case is causing me a lot of confusion. So if execvp() fails then the error is stored in the global variable errno. But this global variable is only accessible from the child process; the parent as an entirely separate process I don't think can see it. Does this mean that I should be calling exit(errno)? Or am I supposed to be doing something else here? Also, if I call exit(errno) how can I get the value of errno back from status in the parent?

My grasp is still a little tenuous so what I'm looking for is either confirmation or correction in my understanding of how to handle these three cases.

Answer

Raju Kunde picture Raju Kunde · Nov 19, 2013

Here is a simple code that I've tried.

if(fork() == 0){
   //do child stuff here
   execvp(cmd,arguments); /*since you want to return errno to parent
                            do a simple exit call with the errno*/
   exit(errno);
}
else{                
    //parent stuff
    int status;
    wait(&status);       /*you made a exit call in child you 
                           need to wait on exit status of child*/
    if(WIFEXITED(status))
         printf("child exited with = %d\n",WEXITSTATUS(status));
                              //you should see the errno here
}