summaryrefslogtreecommitdiff
path: root/src/stdio/popen.c
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-02-09 16:57:14 -0500
committerJakob Kaivo <jkk@ung.org>2019-02-09 16:57:14 -0500
commitc2df77a517e8651a07e323aaa18c6caa2d77eb1b (patch)
tree88ca7ec8494332234a7ff201dac333bd6bf7f0e8 /src/stdio/popen.c
parent7958762d8b94f0aa3babe1d5a8cf0cd57eb3b88f (diff)
merge POSIX.2 identifiers
Diffstat (limited to 'src/stdio/popen.c')
-rw-r--r--src/stdio/popen.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/stdio/popen.c b/src/stdio/popen.c
new file mode 100644
index 00000000..cd1a6572
--- /dev/null
+++ b/src/stdio/popen.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include "string.h"
+#include "errno.h"
+#include "unistd.h"
+#include "wchar.h"
+#include "__nonstd.h"
+
+FILE * popen(const char * command, const char * mode)
+{
+ __ASSERT_NONNULL(command);
+ __ASSERT_NONNULL(mode);
+
+ int direction = 0;
+ if (!strcmp(mode, "w")) {
+ direction = 1;
+ } else if (strcmp(mode, "r")) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ int pd[2];
+ if (pipe(pd) == -1) {
+ return NULL;
+ }
+
+ pid_t child = fork();
+ if (child == -1) {
+ close(pd[0]);
+ close(pd[1]);
+ return NULL;
+ } else if (child == 0) {
+ if (direction == 1) {
+ dup2(pd[0], STDIN_FILENO);
+ } else {
+ dup2(pd[1], STDOUT_FILENO);
+ }
+ close(pd[0]);
+ close(pd[1]);
+ execl("/bin/sh", "sh", "-c", command, (char *)0);
+ return NULL;
+ }
+
+ FILE *p = NULL;
+ if (direction == 1) {
+ p = fdopen(pd[1], "w");
+ } else {
+ p = fdopen(pd[0], "r");
+ }
+
+ if (p == NULL) {
+ return NULL;
+ }
+
+ fwide(p, -1);
+ p->pipe_pid = pid;
+ return p;
+}
+
+/*
+POSIX(2)
+*/
+