#include #include #define tst(a,b) (*mode == 'r'? (b) : (a)) #define RDR 0 #define WTR 1 extern FILE *fdopen(); extern int execl(), fork(), pipe(), close(), fcntl(); static int popen_pid[20]; FILE * popen(cmd, mode) char *cmd, *mode; { int p[2]; register int myside, yourside, pid; if(pipe(p) < 0) return(NULL); myside = tst(p[WTR], p[RDR]); yourside = tst(p[RDR], p[WTR]); if((pid = fork()) == 0) { /* myside and yourside reverse roles in child */ int stdio; stdio = tst(0, 1); (void) close(myside); (void) close(stdio); (void) fcntl(yourside, 0, stdio); (void) close(yourside); (void) execl("/bin/sh", "sh", "-c", cmd, NULL); _exit(1); } if(pid == -1) return(NULL); popen_pid[myside] = pid; (void) close(yourside); return(fdopen(myside, mode)); } int pclose(ptr) FILE *ptr; { register int f, r; int status, (*hstat)(), (*istat)(), (*qstat)(); f = fileno(ptr); (void) fclose(ptr); istat = signal(SIGINT, SIG_IGN); qstat = signal(SIGQUIT, SIG_IGN); hstat = signal(SIGHUP, SIG_IGN); while((r = wait(&status)) != popen_pid[f] && r != -1) ; if(r == -1) status = -1; (void) signal(SIGINT, istat); (void) signal(SIGQUIT, qstat); (void) signal(SIGHUP, hstat); return(status); }