annotate pipes.cpp @ 0:4171b2d4684b default tip

initial commit
author Yasuri <linuxoverwindows@charliesmp.net>
date Sat, 05 Sep 2026 15:35:48 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
1 #include <iostream>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
2 #include <unistd.h>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
3 #include <spawn.h>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
4 #include <cstring>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
5 #include <string>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
6 #include <sys/wait.h>
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
7 extern char** environ;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
8 std::string run_piped(const char* path, char* const argv[], const std::string& input)
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
9 {
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
10 int status;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
11 pid_t pid;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
12 int pipeA[2];
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
13 int pipeB[2];
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
14 pipe(pipeA);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
15 pipe(pipeB);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
16 posix_spawn_file_actions_t actions;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
17 posix_spawn_file_actions_init(&actions); // initialize actions
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
18 posix_spawn_file_actions_adddup2(&actions, pipeA[0], STDIN_FILENO);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
19 posix_spawn_file_actions_adddup2(&actions, pipeB[1], STDOUT_FILENO);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
20 posix_spawn_file_actions_addclose(&actions, pipeA[1]); // closes write end in child
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
21 posix_spawn_file_actions_addclose(&actions, pipeB[0]); // makes sure child doesn't read its own output pipe
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
22 posix_spawn_file_actions_addclose(&actions, pipeA[0]); // close read fd in child
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
23 posix_spawn_file_actions_addclose(&actions, pipeB[1]); // close read fd in child, part 2
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
24 std::cout << "Running posix_spawn()..." << std::endl;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
25 status = posix_spawn(&pid, path, &actions, NULL, const_cast<char* const*>(argv), environ);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
26 close(pipeA[0]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
27 close(pipeB[1]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
28 if (status != 0) {
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
29 posix_spawn_file_actions_destroy(&actions);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
30 close(pipeA[1]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
31 close(pipeB[0]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
32 std::cerr << "posix_spawn failed: " << strerror(status) << std::endl;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
33 return "error";
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
34 }
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
35 write(pipeA[1],input.c_str(), input.size());
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
36 close(pipeA[1]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
37 char buf[256];
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
38 std::string result;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
39 ssize_t n;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
40 while ((n = read(pipeB[0], buf, sizeof(buf))) > 0) {
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
41 result.append(buf, n);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
42 }
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
43 close(pipeB[0]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
44 if (waitpid(pid, &status, 0) == -1) {
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
45 posix_spawn_file_actions_destroy(&actions);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
46 close(pipeA[1]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
47 close(pipeB[0]);
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
48 perror("waitpid");
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
49 return "error";
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
50 }
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
51 return result;
4171b2d4684b initial commit
Yasuri <linuxoverwindows@charliesmp.net>
parents:
diff changeset
52 }