Mercurial > xbps-search-tv
view pipes.cpp @ 2:00b62a080354
fix numerous bugs
| author | Yasuri <yasuri@charliesmp.net> |
|---|---|
| date | Sun, 13 Sep 2026 19:40:11 +0000 |
| parents | 21b543c7aa14 |
| children |
line wrap: on
line source
#include <iostream> #include <unistd.h> #include <spawn.h> #include <cstring> #include <cerrno> #include <string> #include <sys/wait.h> #include "process.h" extern char** environ; std::string run_piped(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_spawnp(&pid, argv[0], &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_spawnp failed for " << argv[0] << ": " << strerror(status) << std::endl; return "error"; } size_t total_written = 0; while (total_written < input.size()) { ssize_t n = write(pipeA[1], input.c_str() + total_written, input.size() - total_written); if (n < 0) { if (errno == EINTR) { continue; // interrupted } perror("write"); break; // error, give up } total_written += n; } 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; }
