I’m trying to solve a problem I’ve got where a child process runs execvp() and needs to let the parent know if it returns. So, after the execvp() returns (because there’s been an error), how can I tell the parent that this particular event has happened so it can handle it.
There’s one method of writing a string of text through the pipe I’m using and then reading that from the parent.. but it seems a bit sloppy. Is there a better way?
Thanks!
Edit: Here is some code I’m trying where I can’t seem to get the read to return.
int errorPipe[2];
signal( SIGPIPE, SIG_IGN );
int oldflags = fcntl (errorPipe[0], F_GETFD, 0);
oldflags |= FD_CLOEXEC;
fcntl (errorPipe[0], F_SETFD, oldflags);
oldflags = fcntl (errorPipe[1], F_GETFD, 0);
oldflags |= FD_CLOEXEC;
fcntl (errorPipe[1], F_SETFD, oldflags);
pipe( errorPipe );
// in the child..
char *error_message = "exec failed";
write( errorPipe[1], error_message, strlen(error_message)+1 );
exit(-1);
// in the parent
printf("read gives: %d\n", read(errorPipe[0], error_read, MAX_LINE_LENGTH) );
The easiest way is a pipe with the
FD_CLOEXECflag set, as then you can detect a successful exec as easily as a failure. In the event of a failure, I’d write whole the error message back to the parent over the pipe, but you could just write the status code or anything else that is meaningful. (Definitely write something though; nothing written has got to be a sign of a successful start of the other executable.)[EDIT]: How to make use of this:
If the parent needs to wait until it knows whether the child successfully ran
execve()(the unlying syscall) then it should do a blockingread()on the pipe. A zero result from that indicates success. (Make sure you’ve gotSIGPIPEignored.)If the parent has some kind of event handling framework based on non-blocking IO and
select()(orpoll()orkqueue()or …) then wait for the pipe to become readable before trying to read the message (which will be zero-length if the child did theexecve()correctly).