diff pipes.cpp @ 0:21b543c7aa14

Initial commit
author Yasuri <yasuri@charliesmp.net>
date Sun, 13 Sep 2026 19:19:56 +0000
parents
children 00b62a080354
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pipes.cpp	Sun Sep 13 19:19:56 2026 +0000
@@ -0,0 +1,55 @@
+#include <iostream>
+#include <unistd.h>
+#include <spawn.h>
+#include <cstring>
+#include <string>
+#include <sys/wait.h>
+#include "process.h"
+extern char** environ;
+std::string run_piped(const char* path, char* const argv[], const std::string& input) 
+{
+    int status;
+    pid_t pid;
+    int pipeA[2];
+    int pipeB[2];
+    if (pipe(pipeA) < 0)
+        return "error";
+    if (pipe(pipeB) < 0)
+        return "error";
+    posix_spawn_file_actions_t actions;
+    posix_spawn_file_actions_init(&actions); // initialize actions
+    posix_spawn_file_actions_adddup2(&actions, pipeA[0], STDIN_FILENO);
+    posix_spawn_file_actions_adddup2(&actions, pipeB[1], STDOUT_FILENO);
+    posix_spawn_file_actions_addclose(&actions, pipeA[1]); // closes write end in child
+    posix_spawn_file_actions_addclose(&actions, pipeB[0]); // makes sure child doesn't read its own output pipe
+    posix_spawn_file_actions_addclose(&actions, pipeA[0]); // close read fd in child
+    posix_spawn_file_actions_addclose(&actions, pipeB[1]); // close read fd in child, part 2
+    status = posix_spawn(&pid, path, &actions, NULL, const_cast<char* const*>(argv), environ);
+    close(pipeA[0]);
+    close(pipeB[1]);
+    if (status != 0) {
+        posix_spawn_file_actions_destroy(&actions);
+        close(pipeA[1]);
+        close(pipeB[0]);
+        std::cerr << "posix_spawn failed: " << strerror(status) << std::endl;
+        return "error";
+    }
+    write(pipeA[1],input.c_str(), input.size());
+    close(pipeA[1]);
+    char buf[256];
+std::string result;
+ssize_t n;
+while ((n = read(pipeB[0], buf, sizeof(buf))) > 0) {
+    result.append(buf, n);
+}
+    close(pipeB[0]);
+    if (waitpid(pid, &status, 0) == -1) {
+        posix_spawn_file_actions_destroy(&actions);
+        close(pipeA[1]);
+        close(pipeB[0]);
+        perror("waitpid");
+        return "error";
+    }
+    posix_spawn_file_actions_destroy(&actions);
+    return result; 
+}