tags:

views:

520

answers:

2

I'm writing a program that has to execute other external processes; right now the program launches the processes' commandlines via popen, grabs any output, and then grabs the exit status via pclose.

What is happening, however, is that for fast-running processes (e.g. the launched process errors out quickly) the pclose call cannot get the exit status (pclose returns -1, errno is ECHILD).

Is there a way for me to mimic the popen/pclose type behavior, except in a manner that guarantees capturing the process end "event" and the resultant return code? How do I avoid the inherent race condition with pclose and the termination of the launched process?

+1  A: 

You can use vfork() and execv().

jeffamaphone
+1  A: 

fork/exec/wait

popen is just a wrapper to simplify the fork/exec calls. If you want to acquire the output of the child, you'll need to create a pipe, call fork, dup the child's file descriptors to the pipe, and then exec. The parent can read the output from the pipe and call wait to get the child's exit status.

William Pursell
As popen is avaialble on windows, which doesn't have a fork, it is obviously not always a wrapper.
anon
I rewrote my code to do this (fork/exec/dup/etc.) and now I am getting intermittent failures on waitpid(...) returning -1/errno=ECHILD. Crap.
Joe
Ok: I figured this out. This code works great. My old code with popen/pclose works great. What did NOT work great was the hidden SIGCHLD handler that was buried in common code that I inherited. OH SNAP. I was basically in a race against that handler (which was simply calling waitpid(-1,...). Lesson learned: read all the man page, and don't assume anything!
Joe