Hmm, I was seeking an elegant way.
Someone told me the following solution, I think this is what I am looking for.
Anyway thanks for your responses.
Mack
> I've been working on ZipOMatic lately, but now that I'm
> close to finishing it, I don't know how to kill the zip process,
> having started it with popen().
>
> It does a lot, but as of yet, no zipping:
>
>
> I need to open a process (or multiple ones), read it's output,
> kill off the process if the user presses Stop, or otherwise wait
> for it to terminate.
>
> And it needs to be thread-safe, so, IIRC, no fork()'ing.
> (there will be BLoopers around)
popen() use fork()
However, the issue there is to get the forked process team id, so that you can kill it or wait his end.
Here's my own popen() implementation, called my_popen() ;-) :
-----8<--------------------------------
static FILE * my_popen
(
Arguments & args,
const char * type,
long * tid
)
{
int p[2];
FILE * fp;
if (*type != 'r' && *type != 'w')
return NULL;
if (pipe(p) < 0)
return NULL;
if ((*tid = fork()) > 0) { /* then we are the parent */
if (*type == 'r') {
close(p[1]);
fp = fdopen(p[0], type);
} else {
close(p[0]);
fp = fdopen(p[1], type);
}
return fp;
} else if (*tid == 0) { /* we're the child */
/* make our thread id the process group leader */
setpgid(0, 0);
if (*type == 'r') {
fflush(stdout);
fflush(stderr);
close(1);
if (dup(p[1]) < 0)
perror("dup of write side of pipe failed");
close(2);
if (dup(p[1]) < 0)
perror("dup of write side of pipe failed");
} else {
close(0);
if (dup(p[0]) < 0)
perror("dup of read side of pipe failed");
}
close(p[0]); /* close since we dup()'ed what we needed */
close(p[1]);
execve(args[0], args, environ);
printf("my_popen(): execve(%s) failed!\n", args[0]);
} else { /* we're having major problems... */
close(p[0]);
close(p[1]);
printf("my_popen(): fork() failure!\n");
}
return NULL;
}
-----8<--------------------------------
Arguments is just a wrapping class around argv arrays... feel free to
move back to classic string arrays.
Here how I use it in one of my pet project:
-----8<--------------------------------
Arguments cmd;
FILE *output;
long cmd_process_id;
bool cancel;
char line[1024];
cmd << "/boot/home/config/bin/cdrecord";
cmd << "dev=0,2,0";
cmd << "speed=4";
cmd << -v"
cmd << "/tmp/cd.img";
output = my_popen(cmd, "r", &cmd_process_id);
if (!output)
return;
while ( ! feof(output) && ! ferror(output) ) {
if ( cancel ) {
kill(-cmd_process_id, SIGINT);
break;
};
fgets(line, sizeof(line), output);
// Do something with process output
};
pclose(output);
------8<-----------------------------