[openbeos] Re: popen() alternatives
- From: "Philippe Houdoin" <philippe.houdoin@xxxxxxx>
- To: openbeos@xxxxxxxxxxxxx
- Date: Mon, 21 Jul 2003 15:06:32 GMT
> 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:
> http://www.kirilla.com/people/jonas/obos/ZipOMatic.zip
>
> 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<-----------------------------
To stop/resume the process, pass SIGSTOP/SIGCONT to kill() instead, it
should works fine.
"Voilà".
Hope it could help...
-Phil
--
Fortune Cookie Says:
"This is a test of the Emergency Broadcast System. If this had been an
actual emergency, do you really think we'd stick around to tell you?"
Other related posts: