This is ppopen.c in view mode; [Download] [Up]
/*
* int ppopen(char *pgm, FILE **frompgm, FILE **topgm)
* int ppclose(FILE *fromcmd, FILE *tocmd)
*
* Like popen(), but hooks up both input and output FILE pointers to a program.
* The "program" may be any valid /bin/sh command.
* ppopen() returns the program's process id if successful, else 0.
* If successful, ``*frompgm'' and ``*topgm'' are filled in with FILE *'s
*
* Take care when using this; deadlock is possible if the program writes a
* large amount of data (> about 8K bytes) to its output while you're still
* writing to its input.
*
* Typical usage might be:
* FILE *frompgm, *topgm;
* ppopen("polymerge", &frompgm, &topgm);
* GeomFSave(g, topgm, "polymerge");
* gg = GeomFLoad(frompgm, "polymerged data");
* ppclose(topgm, frompgm);
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
static int npps = 0;
static unsigned short *pps;
int
ppopen(char *cmd, FILE **frompgm, FILE **topgm)
{
struct pipe { int r, w; } pfrom, pto;
int i, pid;
/* create the communication pipes */
pfrom.r = pfrom.w = -1;
if(pipe(&pfrom) < 0 || pipe(&pto) < 0) {
perror("Can't make pipe");
close(pfrom.r); close(pfrom.w);
return 0;
}
switch(pid = fork()) {
case -1:
perror("Can't fork");
return 0;
case 0: {
static char rats[] = "Can't exec external module: ";
close(pfrom.r);
close(pto.w);
dup2(pto.r, 0);
dup2(pfrom.w, 1);
execl("/bin/sh", "sh", "-c", cmd, NULL);
write(2, rats, sizeof(rats)-1);
perror(cmd);
exit(1);
}
}
close(pto.r);
close(pfrom.w);
*frompgm = fdopen(pfrom.r, "r");
*topgm = fdopen(pto.w, "w");
if(pfrom.r < npps) {
int newsize = (pfrom.r + 10)*sizeof(pps[0]);
npps = pfrom.r + 10;
pps = (unsigned short *) (pps ? realloc(pps, newsize) : malloc(newsize));
bzero(&pps[npps], newsize - npps*sizeof(pps[0]));
pps[pfrom.r] = pid;
}
return pid;
}
ppclose(FILE *frompgm, FILE *topgm)
{
union wait w;
unsigned int fd;
int pid;
if(frompgm == NULL) return -1;
if(topgm) fclose(topgm);
fd = fileno(frompgm);
fclose(frompgm);
if(fd < npps && pps[fd] != 0) {
pps[fd] = 0;
while((pid = wait(&w)) != pps[fd] && pid > 0)
;
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.