Mercurial > xbps-search-tv
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; +}
