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