--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#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];
+ register myside, hisside, pid;
+
+ if(pipe(p) < 0)
+ return NULL;
+ myside = tst(p[WTR], p[RDR]);
+ hisside = tst(p[RDR], p[WTR]);
+ if((pid = vfork()) == 0) {
+ /* myside and hisside reverse roles in child */
+ close(myside);
+ dup2(hisside, tst(0, 1));
+ close(hisside);
+ execl("/bin/sh", "sh", "-c", cmd, 0);
+ _exit(1);
+ }
+ if(pid == -1)
+ return NULL;
+ popen_pid[myside] = pid;
+ close(hisside);
+ return(fdopen(myside, mode));
+}
+
+pclose(ptr)
+FILE *ptr;
+{
+ register f, r, (*hstat)(), (*istat)(), (*qstat)();
+ int status;
+
+ f = fileno(ptr);
+ 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;
+ signal(SIGINT, istat);
+ signal(SIGQUIT, qstat);
+ signal(SIGHUP, hstat);
+ return(status);
+}