1*18246Sserge /* @(#)popen.c 4.7 (Berkeley) 03/04/85 */ 216676Ssam 32024Swnj #include <stdio.h> 42024Swnj #include <signal.h> 517345Slepreau #include <sys/param.h> 616676Ssam 72024Swnj #define tst(a,b) (*mode == 'r'? (b) : (a)) 82024Swnj #define RDR 0 92024Swnj #define WTR 1 102024Swnj 11*18246Sserge extern char *malloc(); 1216676Ssam 13*18246Sserge static int *popen_pid; 14*18246Sserge static int nfiles; 15*18246Sserge 162024Swnj FILE * 172024Swnj popen(cmd,mode) 1816676Ssam char *cmd; 1916676Ssam char *mode; 202024Swnj { 212024Swnj int p[2]; 2216676Ssam int myside, hisside, pid; 232024Swnj 24*18246Sserge if (nfiles <= 0) 25*18246Sserge nfiles = getdtablesize(); 26*18246Sserge if (popen_pid == NULL) { 27*18246Sserge popen_pid = (int *)malloc(nfiles * sizeof *popen_pid); 28*18246Sserge if (popen_pid == NULL) 29*18246Sserge return (NULL); 30*18246Sserge for (pid = 0; pid < nfiles; pid++) 31*18246Sserge popen_pid[pid] = -1; 32*18246Sserge } 3316676Ssam if (pipe(p) < 0) 3416676Ssam return (NULL); 352024Swnj myside = tst(p[WTR], p[RDR]); 362024Swnj hisside = tst(p[RDR], p[WTR]); 37*18246Sserge if ((pid = vfork()) == 0) { 382024Swnj /* myside and hisside reverse roles in child */ 392024Swnj close(myside); 4014718Ssam if (hisside != tst(0, 1)) { 4114718Ssam dup2(hisside, tst(0, 1)); 4214718Ssam close(hisside); 4314718Ssam } 44*18246Sserge execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); 45*18246Sserge _exit(127); 462024Swnj } 4716676Ssam if (pid == -1) { 4815073Skarels close(myside); 4915073Skarels close(hisside); 5016676Ssam return (NULL); 5115073Skarels } 522024Swnj popen_pid[myside] = pid; 532024Swnj close(hisside); 5416676Ssam return (fdopen(myside, mode)); 552024Swnj } 562024Swnj 572024Swnj pclose(ptr) 5816676Ssam FILE *ptr; 592024Swnj { 6016676Ssam int child, pid, status, omask; 612024Swnj 6216676Ssam child = popen_pid[fileno(ptr)]; 63*18246Sserge popen_pid[fileno(ptr)] = -1; 642024Swnj fclose(ptr); 65*18246Sserge if (child == -1) 66*18246Sserge return (-1); 67*18246Sserge omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 6816676Ssam while ((pid = wait(&status)) != child && pid != -1) 692024Swnj ; 7016676Ssam (void) sigsetmask(omask); 7116676Ssam return (pid == -1 ? -1 : status); 722024Swnj } 73