1*16676Ssam /* @(#)popen.c 4.5 (Berkeley) 07/06/84 */ 2*16676Ssam 32024Swnj #include <stdio.h> 42024Swnj #include <signal.h> 5*16676Ssam 62024Swnj #define tst(a,b) (*mode == 'r'? (b) : (a)) 72024Swnj #define RDR 0 82024Swnj #define WTR 1 92024Swnj 10*16676Ssam static int popen_pid[20]; 11*16676Ssam 122024Swnj FILE * 132024Swnj popen(cmd,mode) 14*16676Ssam char *cmd; 15*16676Ssam char *mode; 162024Swnj { 172024Swnj int p[2]; 18*16676Ssam int myside, hisside, pid; 192024Swnj 20*16676Ssam if (pipe(p) < 0) 21*16676Ssam return (NULL); 222024Swnj myside = tst(p[WTR], p[RDR]); 232024Swnj hisside = tst(p[RDR], p[WTR]); 24*16676Ssam if ((pid = fork()) == 0) { 252024Swnj /* myside and hisside reverse roles in child */ 262024Swnj close(myside); 2714718Ssam if (hisside != tst(0, 1)) { 2814718Ssam dup2(hisside, tst(0, 1)); 2914718Ssam close(hisside); 3014718Ssam } 312024Swnj execl("/bin/sh", "sh", "-c", cmd, 0); 322024Swnj _exit(1); 332024Swnj } 34*16676Ssam if (pid == -1) { 3515073Skarels close(myside); 3615073Skarels close(hisside); 37*16676Ssam return (NULL); 3815073Skarels } 392024Swnj popen_pid[myside] = pid; 402024Swnj close(hisside); 41*16676Ssam return (fdopen(myside, mode)); 422024Swnj } 432024Swnj 442024Swnj pclose(ptr) 45*16676Ssam FILE *ptr; 462024Swnj { 47*16676Ssam int child, pid, status, omask; 482024Swnj 49*16676Ssam child = popen_pid[fileno(ptr)]; 502024Swnj fclose(ptr); 51*16676Ssam #define mask(s) (1 << ((s)-1)) 52*16676Ssam omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP)); 53*16676Ssam while ((pid = wait(&status)) != child && pid != -1) 542024Swnj ; 55*16676Ssam (void) sigsetmask(omask); 56*16676Ssam return (pid == -1 ? -1 : status); 572024Swnj } 58