summaryrefslogtreecommitdiff
path: root/libc/stdio/popen.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/popen.c')
-rw-r--r--libc/stdio/popen.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
new file mode 100644
index 000000000..a07c411eb
--- /dev/null
+++ b/libc/stdio/popen.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+FILE *popen(command, rw)
+char *command;
+char *rw;
+{
+ int pipe_fd[2];
+ int pid, reading;
+
+ if (pipe(pipe_fd) < 0)
+ return NULL;
+ reading = (rw[0] == 'r');
+
+ pid = vfork();
+ if (pid < 0) {
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ return NULL;
+ }
+ if (pid == 0) {
+ close(pipe_fd[!reading]);
+ close(reading);
+ if (pipe_fd[reading] != reading) {
+ dup2(pipe_fd[reading], reading);
+ close(pipe_fd[reading]);
+ }
+
+ execl("/bin/sh", "sh", "-c", command, (char *) 0);
+ _exit(255);
+ }
+
+ close(pipe_fd[reading]);
+ return fdopen(pipe_fd[!reading], rw);
+}
+
+int pclose(fd)
+FILE *fd;
+{
+ int waitstat;
+
+ if (fclose(fd) != 0)
+ return EOF;
+ wait(&waitstat);
+ return waitstat;
+}