/* @(#)popen.c 4.5 (Berkeley) 07/06/84 */ #include #include #define tst(a,b) (*mode == 'r'? (b) : (a)) #define RDR 0 #define WTR 1 static int popen_pid[20]; FILE * popen(cmd,mode) char *cmd; char *mode; { int p[2]; int myside, hisside, pid; if (pipe(p) < 0) return (NULL); myside = tst(p[WTR], p[RDR]); hisside = tst(p[RDR], p[WTR]); if ((pid = fork()) == 0) { /* myside and hisside reverse roles in child */ close(myside); if (hisside != tst(0, 1)) { dup2(hisside, tst(0, 1)); close(hisside); } execl("/bin/sh", "sh", "-c", cmd, 0); _exit(1); } if (pid == -1) { close(myside); close(hisside); return (NULL); } popen_pid[myside] = pid; close(hisside); return (fdopen(myside, mode)); } pclose(ptr) FILE *ptr; { int child, pid, status, omask; child = popen_pid[fileno(ptr)]; fclose(ptr); #define mask(s) (1 << ((s)-1)) omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP)); while ((pid = wait(&status)) != child && pid != -1) ; (void) sigsetmask(omask); return (pid == -1 ? -1 : status); }