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.