1*219b2ee8SDavid du Colombier #include <stdlib.h> 2*219b2ee8SDavid du Colombier #include <stdio.h> 3*219b2ee8SDavid du Colombier #include <sys/types.h> 4*219b2ee8SDavid du Colombier #include <unistd.h> 5*219b2ee8SDavid du Colombier #include <sys/wait.h> 6*219b2ee8SDavid du Colombier 7*219b2ee8SDavid du Colombier #define MAXFORKS 20 8*219b2ee8SDavid du Colombier #define NSYSFILE 3 9*219b2ee8SDavid du Colombier #define tst(a,b) (*mode == 'r'? (b) : (a)) 10*219b2ee8SDavid du Colombier #define RDR 0 11*219b2ee8SDavid du Colombier #define WTR 1 12*219b2ee8SDavid du Colombier 13*219b2ee8SDavid du Colombier struct a_fork { 14*219b2ee8SDavid du Colombier short done; 15*219b2ee8SDavid du Colombier short fd; 16*219b2ee8SDavid du Colombier int pid; 17*219b2ee8SDavid du Colombier int status; 18*219b2ee8SDavid du Colombier }; 19*219b2ee8SDavid du Colombier static struct a_fork the_fork[MAXFORKS]; 20*219b2ee8SDavid du Colombier 21*219b2ee8SDavid du Colombier FILE * 22*219b2ee8SDavid du Colombier popen(char *cmd, char *mode) 23*219b2ee8SDavid du Colombier { 24*219b2ee8SDavid du Colombier int p[2]; 25*219b2ee8SDavid du Colombier int myside, hisside, pid; 26*219b2ee8SDavid du Colombier int i, ind; 27*219b2ee8SDavid du Colombier 28*219b2ee8SDavid du Colombier for (ind = 0; ind < MAXFORKS; ind++) 29*219b2ee8SDavid du Colombier if (the_fork[ind].pid == 0) 30*219b2ee8SDavid du Colombier break; 31*219b2ee8SDavid du Colombier if (ind == MAXFORKS) 32*219b2ee8SDavid du Colombier return NULL; 33*219b2ee8SDavid du Colombier if(pipe(p) < 0) 34*219b2ee8SDavid du Colombier return NULL; 35*219b2ee8SDavid du Colombier myside = tst(p[WTR], p[RDR]); 36*219b2ee8SDavid du Colombier hisside = tst(p[RDR], p[WTR]); 37*219b2ee8SDavid du Colombier switch (pid = fork()) { 38*219b2ee8SDavid du Colombier case -1: 39*219b2ee8SDavid du Colombier return NULL; 40*219b2ee8SDavid du Colombier case 0: 41*219b2ee8SDavid du Colombier /* myside and hisside reverse roles in child */ 42*219b2ee8SDavid du Colombier close(myside); 43*219b2ee8SDavid du Colombier dup2(hisside, tst(0, 1)); 44*219b2ee8SDavid du Colombier for (i=NSYSFILE; i<FOPEN_MAX; i++) 45*219b2ee8SDavid du Colombier close(i); 46*219b2ee8SDavid du Colombier execl("/bin/ape/sh", "sh", "-c", cmd, 0); 47*219b2ee8SDavid du Colombier _exit(1); 48*219b2ee8SDavid du Colombier default: 49*219b2ee8SDavid du Colombier the_fork[ind].pid = pid; 50*219b2ee8SDavid du Colombier the_fork[ind].fd = myside; 51*219b2ee8SDavid du Colombier the_fork[ind].done = 0; 52*219b2ee8SDavid du Colombier close(hisside); 53*219b2ee8SDavid du Colombier return(fdopen(myside, mode)); 54*219b2ee8SDavid du Colombier } 55*219b2ee8SDavid du Colombier } 56*219b2ee8SDavid du Colombier 57*219b2ee8SDavid du Colombier int 58*219b2ee8SDavid du Colombier pclose(FILE *ptr) 59*219b2ee8SDavid du Colombier { 60*219b2ee8SDavid du Colombier int f, r, ind; 61*219b2ee8SDavid du Colombier int status; 62*219b2ee8SDavid du Colombier 63*219b2ee8SDavid du Colombier f = fileno(ptr); 64*219b2ee8SDavid du Colombier fclose(ptr); 65*219b2ee8SDavid du Colombier for (ind = 0; ind < MAXFORKS; ind++) 66*219b2ee8SDavid du Colombier if (the_fork[ind].fd == f && the_fork[ind].pid != 0) 67*219b2ee8SDavid du Colombier break; 68*219b2ee8SDavid du Colombier if (ind == MAXFORKS) 69*219b2ee8SDavid du Colombier return 0; 70*219b2ee8SDavid du Colombier if (!the_fork[ind].done) { 71*219b2ee8SDavid du Colombier do { 72*219b2ee8SDavid du Colombier r = wait(&status); 73*219b2ee8SDavid du Colombier for (f = 0; f < MAXFORKS; f++) 74*219b2ee8SDavid du Colombier if (the_fork[f].pid == r) { 75*219b2ee8SDavid du Colombier the_fork[f].done = 1; 76*219b2ee8SDavid du Colombier the_fork[f].status = status; 77*219b2ee8SDavid du Colombier break; 78*219b2ee8SDavid du Colombier } 79*219b2ee8SDavid du Colombier } while(r != the_fork[ind].pid && r != -1); 80*219b2ee8SDavid du Colombier the_fork[ind].status = r == -1 ? -1 : status; 81*219b2ee8SDavid du Colombier } 82*219b2ee8SDavid du Colombier the_fork[ind].pid = 0; 83*219b2ee8SDavid du Colombier return (the_fork[ind].status); 84*219b2ee8SDavid du Colombier } 85