execvp/fork -- how to catch unsuccessful executions?

c, exec, execvp, fork

Solution

This is a classic problem with a very elegant solution. Before forking, create a `pipe` in the parent. After `fork`, the parent should close the writing end of the pipe, and block attempting to `read` from the reading end. The child should close the reading end and set the close-on-exec flag, using `fcntl`, for the writing end.

Now, if the child calls `execvp` successfully, the writing end of the pipe will be closed with no data, and `read` in the parent will return 0. If `execvp` fails in the child, write the error code to the pipe, and `read` in the parent will return nonzero, having read the error code for the parent to handle.

Problem

Right now I'm writing a C program that must execute a child process. I'm not doing multiple child processes simultaneously or anything, so this is fairly straightforward. I am definitely executing the built-in shell programs (i.e. things like cat and echo) successfully, but I also need to be able to tell when one of these programs fails to execute successfully. I'm trying this with the following simplified code: ``` int returnStatus; // The return status of the child process. pid_t pid = fork(); if (pid == -1) // error with forking. { // Not really important for this question. } else if (pid == 0) // We're in the child process. { execvp(programName, programNameAndCommandsArray); // vars declared above fork(). // If this code executes the execution has failed. exit(127); // This exit code was taken from a exec tutorial -- why 127? } else // We're in the parent process. { wait(&returnStatus); // Wait for the child process to exit. if (returnStatus == -1) // The child process execution failed. { // Log an error of execution. } } ``` So for example, if I try to execute rm fileThatDoesntExist.txt, I would like to consider that a failure since the file didn't exist. How can I accomplish this? Also, while that execvp() call successfully executes built-in shell programs, it doesn't execute programs in the current directory of the executable (i.e. the program that this code is running inside of); Is there something else that I have to do in order to get it to run programs in the current directory? Thanks!

Original source

Related problems