Tue, 21 Jan 2025 18:25:59 +0100
add utility to spawn processes and retrieve their output
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1 | /* Copyright 2025 Mike Becker. All rights reserved. |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
2 | * |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
3 | * Redistribution and use in source and binary forms, with or without |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
4 | * modification, are permitted provided that the following conditions are met: |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
5 | * |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
6 | * 1. Redistributions of source code must retain the above copyright |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
7 | * notice, this list of conditions and the following disclaimer. |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
8 | * |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
9 | * 2. Redistributions in binary form must reproduce the above copyright |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer in the |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
11 | * documentation and/or other materials provided with the distribution. |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
12 | * |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
16 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
21 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
22 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
23 | */ |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
24 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
25 | #include "process.h" |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
26 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
27 | #include <cstdio> |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
28 | #include <cstdlib> |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
29 | #include <fcntl.h> |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
30 | #include <unistd.h> |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
31 | #include <sys/wait.h> |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
32 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
33 | using namespace fm; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
34 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
35 | process::process(std::string path): m_path(std::move(path)) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
36 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
37 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
38 | bool process::exec(std::vector<std::string> args) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
39 | // fd-pair for the pipe |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
40 | int pipefd[2]; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
41 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
42 | if (pipe(pipefd)) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
43 | perror("pipe"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
44 | return false; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
45 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
46 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
47 | pid_t pid = fork(); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
48 | if (pid == 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
49 | // connect the pipe and close the end we don't use |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
50 | if (dup2(pipefd[1], STDOUT_FILENO) == -1) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
51 | perror("pipe"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
52 | exit(EXIT_FAILURE); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
53 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
54 | close(pipefd[0]); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
55 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
56 | // create the execv argument list |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
57 | char *argv[args.size() + 2] = {}; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
58 | auto slash = m_path.find_last_of('/'); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
59 | if (slash == std::string::npos) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
60 | argv[0] = m_path.data(); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
61 | } else { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
62 | argv[0] = m_path.data() + slash + 1; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
63 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
64 | unsigned i = 0; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
65 | for (auto&& arg : args) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
66 | argv[++i] = arg.data(); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
67 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
68 | argv[args.size() + 1] = nullptr; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
69 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
70 | // execute the child program |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
71 | if (execv(m_path.c_str(), argv)) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
72 | perror("execl"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
73 | exit(EXIT_FAILURE); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
74 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
75 | return true; // unreachable, but the compiler doesn't know that |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
76 | } else if (pid > 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
77 | // close the end of the pipe we don't use |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
78 | close(pipefd[1]); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
79 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
80 | // read all the output |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
81 | char buf[64]; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
82 | ssize_t r; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
83 | while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
84 | m_output.append(buf, r); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
85 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
86 | if (r < 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
87 | perror("read"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
88 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
89 | close(pipefd[0]); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
90 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
91 | // wait for the process to completely finish |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
92 | int status = -1; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
93 | waitpid(pid, &status, 0); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
94 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
95 | return status == 0; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
96 | } else { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
97 | perror("fork"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
98 | return false; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
99 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
100 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
101 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
102 | const std::string &process::output() const { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
103 | return m_output; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
104 | } |