Don't use popen()
, write your own wrapper that does what you'd like.
It's fairly straightforward to fork()
, and then replace stdin
& stdout
by using dup2()
, and then calling exec()
on your child.
That way, your parent will have the exact child PID, and you can use
kill()
on that.
Google search for "popen2() implementation" for some sample code on
how to implement what popen()
is doing. It's only a dozen or so lines
long. Taken from dzone.com we can see
an example that looks like this:
#define READ 0
#define WRITE 1
pid_t
popen2(const char *command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execl("/bin/sh", "sh", "-c", command, NULL);
perror("execl");
exit(1);
}
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
NB: Seems like popen2() is what you want, but my distribution doesn't seem to come with this method.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…