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.