I see two solutions here:
- The neat one: you
fork()
,pipe()
andexecve()
(or anything in theexec
family of course...) "manually", then it is going to be up to you to decide if you want to let your children become zombies or not. (i.e. towait()
for them or not) - The ugly one: if you're sure you only have one of this child process running at any given time, you could use
sysctl()
to check if there is any process running with this name before you callpclose()
... yuk.
I strongly advise the neat way here, or you could just ask whomever responsible to fix that infinite loop in your third party tool haha.
Good luck!
EDIT:
For you first question: I don't know. Doing some researches on how to find processes by name using sysctl()
shoud tell you what you need to know, I myself have never pushed it this far.
For your second and third question: popen()
is basically a wrapper to fork()
+ pipe()
+ dup2()
+ execl()
.
fork()
duplicates the process, execl()
replaces the duplicated process' image with a new one, pipe()
handles inter process communication and dup2()
is used to redirect the output... And then pclose()
will wait()
for the duplicated process to die, which is why we're here.
If you want to know more, you should check this answer where I've recently explained how to perform a simple fork with standard IPC. In this case, it's just a bit more complicated as you have to use dup2()
to redirect the standard output to your pipe.
You should also take a look at popen()/pclose()
source codes, as they are of course open source.
Finally, here's a brief example, I cannot make it clearer than that:
int pipefd[2];
pipe(pipefd);
if (fork() == 0) // I'm the child
{
close(pipefd[0]); // I'm not going to read from this pipe
dup2(pipefd[1], 1); // redirect standard output to the pipe
close(pipefd[1]); // it has been duplicated, close it as we don't need it anymore
execve()/execl()/execsomething()... // execute the program you want
}
else // I'm the parent
{
close(pipefd[1]); // I'm not going to write to this pipe
while (read(pipefd[0], &buf, 1) > 0) // read while EOF
write(1, &buf, 1);
close(pipefd[1]); // cleaning
}
And as always, remember to read the man pages and to check all your return values.
Again, good luck!