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