1*2024Swnj /* @(#)popen.c 4.1 (Berkeley) 12/21/80 */ 2*2024Swnj #include <stdio.h> 3*2024Swnj #include <signal.h> 4*2024Swnj #define tst(a,b) (*mode == 'r'? (b) : (a)) 5*2024Swnj #define RDR 0 6*2024Swnj #define WTR 1 7*2024Swnj static int popen_pid[20]; 8*2024Swnj 9*2024Swnj FILE * 10*2024Swnj popen(cmd,mode) 11*2024Swnj char *cmd; 12*2024Swnj char *mode; 13*2024Swnj { 14*2024Swnj int p[2]; 15*2024Swnj register myside, hisside, pid; 16*2024Swnj 17*2024Swnj if(pipe(p) < 0) 18*2024Swnj return NULL; 19*2024Swnj myside = tst(p[WTR], p[RDR]); 20*2024Swnj hisside = tst(p[RDR], p[WTR]); 21*2024Swnj if((pid = vfork()) == 0) { 22*2024Swnj /* myside and hisside reverse roles in child */ 23*2024Swnj close(myside); 24*2024Swnj dup2(hisside, tst(0, 1)); 25*2024Swnj close(hisside); 26*2024Swnj execl("/bin/sh", "sh", "-c", cmd, 0); 27*2024Swnj _exit(1); 28*2024Swnj } 29*2024Swnj if(pid == -1) 30*2024Swnj return NULL; 31*2024Swnj popen_pid[myside] = pid; 32*2024Swnj close(hisside); 33*2024Swnj return(fdopen(myside, mode)); 34*2024Swnj } 35*2024Swnj 36*2024Swnj pclose(ptr) 37*2024Swnj FILE *ptr; 38*2024Swnj { 39*2024Swnj register f, r, (*hstat)(), (*istat)(), (*qstat)(); 40*2024Swnj int status; 41*2024Swnj 42*2024Swnj f = fileno(ptr); 43*2024Swnj fclose(ptr); 44*2024Swnj istat = signal(SIGINT, SIG_IGN); 45*2024Swnj qstat = signal(SIGQUIT, SIG_IGN); 46*2024Swnj hstat = signal(SIGHUP, SIG_IGN); 47*2024Swnj while((r = wait(&status)) != popen_pid[f] && r != -1) 48*2024Swnj ; 49*2024Swnj if(r == -1) 50*2024Swnj status = -1; 51*2024Swnj signal(SIGINT, istat); 52*2024Swnj signal(SIGQUIT, qstat); 53*2024Swnj signal(SIGHUP, hstat); 54*2024Swnj return(status); 55*2024Swnj } 56