Sat, 01 Feb 2025 14:19:36 +0100
improve readability
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 | |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
35 | void process::setbin(std::string path) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
36 | m_path = std::move(path); |
2
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 | |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
39 | void process::chdir(std::string path) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
40 | m_dir = std::move(path); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
41 | } |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
42 | |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
43 | int process::exec(std::vector<std::string> args, bool capture) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
44 | m_output.clear(); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
45 | |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
46 | // fd-pair for the pipe |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
47 | int pipefd[2]; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
48 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
49 | if (pipe(pipefd)) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
50 | perror("pipe"); |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
51 | return -1; |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
52 | } |
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 | pid_t pid = fork(); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
55 | if (pid == 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
56 | // 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
|
57 | 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
|
58 | perror("pipe"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
59 | exit(EXIT_FAILURE); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
60 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
61 | close(pipefd[0]); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
62 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
63 | // create the execv argument list |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
64 | char *argv[args.size() + 2] = {}; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
65 | 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
|
66 | if (slash == std::string::npos) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
67 | argv[0] = m_path.data(); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
68 | } else { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
69 | 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
|
70 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
71 | unsigned i = 0; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
72 | for (auto&& arg : args) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
73 | argv[++i] = arg.data(); |
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 | argv[args.size() + 1] = nullptr; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
76 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
77 | // execute the child program |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
78 | if (::chdir(m_dir.c_str())) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
79 | perror("chdir"); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
80 | exit(EXIT_FAILURE); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
81 | } |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
82 | 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
|
83 | perror("execl"); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
84 | exit(EXIT_FAILURE); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
85 | } |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
86 | return 0; // unreachable, but the compiler doesn't know that |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
87 | } else if (pid > 0) { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
88 | // 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
|
89 | close(pipefd[1]); |
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 | // read all the output |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
92 | if (capture) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
93 | char buf[64]; |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
94 | ssize_t r; |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
95 | while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
96 | m_output.append(buf, r); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
97 | } |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
98 | if (r < 0) { |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
99 | perror("read"); |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
100 | } |
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
101 | close(pipefd[0]); |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
102 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
103 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
104 | // 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
|
105 | int status = -1; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
106 | waitpid(pid, &status, 0); |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
107 | |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
108 | return status; |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
109 | } else { |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
110 | perror("fork"); |
4
82680ce258d6
add automatic pull/udate of repositories
Mike Becker <universe@uap-core.de>
parents:
2
diff
changeset
|
111 | return -1; |
2
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
112 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
113 | } |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
114 | |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
115 | 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
|
116 | return m_output; |
7384ebae6b7c
add utility to spawn processes and retrieve their output
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
117 | } |