1*17345Slepreau /* @(#)popen.c 4.6 (Berkeley) 11/10/84 */ 216676Ssam 32024Swnj #include <stdio.h> 42024Swnj #include <signal.h> 5*17345Slepreau #include <sys/param.h> 616676Ssam 72024Swnj #define tst(a,b) (*mode == 'r'? (b) : (a)) 82024Swnj #define RDR 0 92024Swnj #define WTR 1 102024Swnj 11*17345Slepreau static int popen_pid[NOFILE]; 1216676Ssam 132024Swnj FILE * 142024Swnj popen(cmd,mode) 1516676Ssam char *cmd; 1616676Ssam char *mode; 172024Swnj { 182024Swnj int p[2]; 1916676Ssam int myside, hisside, pid; 202024Swnj 2116676Ssam if (pipe(p) < 0) 2216676Ssam return (NULL); 232024Swnj myside = tst(p[WTR], p[RDR]); 242024Swnj hisside = tst(p[RDR], p[WTR]); 2516676Ssam if ((pid = fork()) == 0) { 262024Swnj /* myside and hisside reverse roles in child */ 272024Swnj close(myside); 2814718Ssam if (hisside != tst(0, 1)) { 2914718Ssam dup2(hisside, tst(0, 1)); 3014718Ssam close(hisside); 3114718Ssam } 322024Swnj execl("/bin/sh", "sh", "-c", cmd, 0); 332024Swnj _exit(1); 342024Swnj } 3516676Ssam if (pid == -1) { 3615073Skarels close(myside); 3715073Skarels close(hisside); 3816676Ssam return (NULL); 3915073Skarels } 402024Swnj popen_pid[myside] = pid; 412024Swnj close(hisside); 4216676Ssam return (fdopen(myside, mode)); 432024Swnj } 442024Swnj 452024Swnj pclose(ptr) 4616676Ssam FILE *ptr; 472024Swnj { 4816676Ssam int child, pid, status, omask; 492024Swnj 5016676Ssam child = popen_pid[fileno(ptr)]; 512024Swnj fclose(ptr); 5216676Ssam #define mask(s) (1 << ((s)-1)) 5316676Ssam omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP)); 5416676Ssam while ((pid = wait(&status)) != child && pid != -1) 552024Swnj ; 5616676Ssam (void) sigsetmask(omask); 5716676Ssam return (pid == -1 ? -1 : status); 582024Swnj } 59