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