WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
Process.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <initializer_list>
8#include <memory>
9#include <span>
10#include <string>
11#include <string_view>
12
13#include <uv.h>
14
15#include "wpi/net/uv/Handle.hpp"
16#include "wpi/util/Signal.h"
17#include "wpi/util/SmallVector.hpp"
18
19namespace wpi::net::uv {
20
21class Loop;
22class Pipe;
23
24/**
25 * Process handle.
26 * Process handles will spawn a new process and allow the user to control it
27 * and establish communication channels with it using streams.
28 */
29class Process final : public HandleImpl<Process, uv_process_t> {
30 struct private_init {};
31
32 public:
33 explicit Process(const private_init&) {}
34 ~Process() noexcept override = default;
35
36 /**
37 * Structure for Spawn() option temporaries. This is a reference type, so if
38 * this value is stored outside of a temporary, be careful about overwriting
39 * what it points to.
40 */
41 struct Option {
56
58
59 /*implicit*/ Option(const char* arg) { // NOLINT
60 m_data.str = arg;
61 }
62
63 /*implicit*/ Option(const std::string& arg) { // NOLINT
64 m_data.str = arg.data();
65 }
66
67 /*implicit*/ Option(std::string_view arg) // NOLINT
68 : m_strData(arg) {
69 m_data.str = m_strData.c_str();
70 }
71
72 /*implicit*/ Option(const wpi::util::SmallVectorImpl<char>& arg) // NOLINT
73 : m_strData(arg.data(), arg.size()) {
74 m_data.str = m_strData.c_str();
75 }
76
77 explicit Option(Type type) : m_type(type) {}
78
80 std::string m_strData;
81 union {
82 const char* str;
83 uv_uid_t uid;
84 uv_gid_t gid;
85 unsigned int flags;
86 struct {
87 size_t index;
88 union {
89 int fd;
91 };
92 unsigned int flags;
93 } stdio;
94 } m_data;
95 };
96
97 /**
98 * Set environment variable for the subprocess. If not set, the parent's
99 * environment is used.
100 * @param env environment variable
101 */
102 static Option Env(std::string_view env) {
104 o.m_strData = env;
105 o.m_data.str = o.m_strData.c_str();
106 return o;
107 }
108
109 /**
110 * Set the current working directory for the subprocess.
111 * @param cwd current working directory
112 */
113 static Option Cwd(std::string_view cwd) {
115 o.m_strData = cwd;
116 o.m_data.str = o.m_strData.c_str();
117 return o;
118 }
119
120 /**
121 * Set the child process' user id.
122 * @param uid user id
123 */
124 static Option Uid(uv_uid_t uid) {
126 o.m_data.uid = uid;
127 return o;
128 }
129
130 /**
131 * Set the child process' group id.
132 * @param gid group id
133 */
134 static Option Gid(uv_gid_t gid) {
136 o.m_data.gid = gid;
137 return o;
138 }
139
140 /**
141 * Set spawn flags.
142 * @param flags Bitmask values from uv_process_flags.
143 */
144 static Option SetFlags(unsigned int flags) {
146 o.m_data.flags = flags;
147 return o;
148 }
149
150 /**
151 * Clear spawn flags.
152 * @param flags Bitmask values from uv_process_flags.
153 */
154 static Option ClearFlags(unsigned int flags) {
156 o.m_data.flags = flags;
157 return o;
158 }
159
160 /**
161 * Explicitly ignore a stdio.
162 * @param index stdio index
163 */
164 static Option StdioIgnore(size_t index) {
167 return o;
168 }
169
170 /**
171 * Inherit a file descriptor from the parent process.
172 * @param index stdio index
173 * @param fd parent file descriptor
174 */
175 static Option StdioInherit(size_t index, int fd) {
178 o.m_data.stdio.fd = fd;
179 return o;
180 }
181
182 /**
183 * Inherit a pipe from the parent process.
184 * @param index stdio index
185 * @param pipe pipe
186 */
187 static Option StdioInherit(size_t index, Pipe& pipe) {
190 o.m_data.stdio.pipe = &pipe;
191 return o;
192 }
193
194 /**
195 * Create a pipe between the child and the parent.
196 * @param index stdio index
197 * @param pipe pipe
198 * @param flags Some combination of UV_READABLE_PIPE, UV_WRITABLE_PIPE, and
199 * UV_OVERLAPPED_PIPE (Windows only, ignored on Unix).
200 */
201 static Option StdioCreatePipe(size_t index, Pipe& pipe, unsigned int flags) {
204 o.m_data.stdio.pipe = &pipe;
206 return o;
207 }
208
209 /**
210 * Disables inheritance for file descriptors / handles that this process
211 * inherited from its parent. The effect is that child processes spawned
212 * by this process don't accidentally inherit these handles.
213 *
214 * It is recommended to call this function as early in your program as
215 * possible, before the inherited file descriptors can be closed or
216 * duplicated.
217 */
219
220 /**
221 * Starts a process. If the process is not successfully spawned, an error
222 * is generated on the loop and this function returns nullptr.
223 *
224 * Possible reasons for failing to spawn would include (but not be limited to)
225 * the file to execute not existing, not having permissions to use the setuid
226 * or setgid specified, or not having enough memory to allocate for the new
227 * process.
228 *
229 * @param loop Loop object where this handle runs.
230 * @param file Path pointing to the program to be executed
231 * @param options Process options
232 */
233 static std::shared_ptr<Process> SpawnArray(Loop& loop, std::string_view file,
234 std::span<const Option> options);
235
236 static std::shared_ptr<Process> SpawnArray(
237 Loop& loop, std::string_view file,
238 std::initializer_list<Option> options) {
239 return SpawnArray(loop, file, {options.begin(), options.end()});
240 }
241
242 template <typename... Args>
243 static std::shared_ptr<Process> Spawn(Loop& loop, std::string_view file,
244 const Args&... options) {
245 return SpawnArray(loop, file, {options...});
246 }
247
248 /**
249 * Starts a process. If the process is not successfully spawned, an error
250 * is generated on the loop and this function returns nullptr.
251 *
252 * Possible reasons for failing to spawn would include (but not be limited to)
253 * the file to execute not existing, not having permissions to use the setuid
254 * or setgid specified, or not having enough memory to allocate for the new
255 * process.
256 *
257 * @param loop Loop object where this handle runs.
258 * @param file Path pointing to the program to be executed
259 * @param options Process options
260 */
261 static std::shared_ptr<Process> SpawnArray(const std::shared_ptr<Loop>& loop,
262 std::string_view file,
263 std::span<const Option> options) {
264 return SpawnArray(*loop, file, options);
265 }
266
267 static std::shared_ptr<Process> SpawnArray(
268 const std::shared_ptr<Loop>& loop, std::string_view file,
269 std::initializer_list<Option> options) {
270 return SpawnArray(*loop, file, options);
271 }
272
273 template <typename... Args>
274 static std::shared_ptr<Process> Spawn(const std::shared_ptr<Loop>& loop,
275 std::string_view file,
276 const Args&... options) {
277 return SpawnArray(*loop, file, {options...});
278 }
279
280 /**
281 * Sends the specified signal to the process.
282 * @param signum signal number
283 */
284 void Kill(int signum) { Invoke(&uv_process_kill, GetRaw(), signum); }
285
286 /**
287 * Sends the specified signal to the given PID.
288 * @param pid process ID
289 * @param signum signal number
290 * @return 0 on success, otherwise error code.
291 */
292 static int Kill(int pid, int signum) noexcept { return uv_kill(pid, signum); }
293
294 /**
295 * Get the process ID.
296 * @return Process ID.
297 */
298 uv_pid_t GetPid() const noexcept { return GetRaw()->pid; }
299
300 /**
301 * Signal generated when the process exits. The parameters are the exit
302 * status and the signal that caused the process to terminate, if any.
303 */
305};
306
307} // namespace wpi::net::uv
then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file
Definition ThirdPartyNotices.txt:204
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Returns a named argument to be used in a formatting function.
Definition base.h:2846
@ index
Definition base.h:690
bool Invoke(F &&f, Args &&... args) const
Definition Handle.hpp:265
uv_process_t * GetRaw() const noexcept
Definition Handle.hpp:303
Event loop.
Definition Loop.hpp:35
Pipe handle.
Definition Pipe.hpp:26
static std::shared_ptr< Process > SpawnArray(const std::shared_ptr< Loop > &loop, std::string_view file, std::initializer_list< Option > options)
Definition Process.hpp:267
static Option StdioCreatePipe(size_t index, Pipe &pipe, unsigned int flags)
Create a pipe between the child and the parent.
Definition Process.hpp:201
Process(const private_init &)
Definition Process.hpp:33
static Option StdioIgnore(size_t index)
Explicitly ignore a stdio.
Definition Process.hpp:164
static std::shared_ptr< Process > SpawnArray(const std::shared_ptr< Loop > &loop, std::string_view file, std::span< const Option > options)
Starts a process.
Definition Process.hpp:261
static std::shared_ptr< Process > SpawnArray(Loop &loop, std::string_view file, std::span< const Option > options)
Starts a process.
static Option Uid(uv_uid_t uid)
Set the child process' user id.
Definition Process.hpp:124
wpi::util::sig::Signal< int64_t, int > exited
Signal generated when the process exits.
Definition Process.hpp:304
static std::shared_ptr< Process > Spawn(Loop &loop, std::string_view file, const Args &... options)
Definition Process.hpp:243
void Kill(int signum)
Sends the specified signal to the process.
Definition Process.hpp:284
static Option Gid(uv_gid_t gid)
Set the child process' group id.
Definition Process.hpp:134
~Process() noexcept override=default
static void DisableStdioInheritance()
Disables inheritance for file descriptors / handles that this process inherited from its parent.
Definition Process.hpp:218
uv_pid_t GetPid() const noexcept
Get the process ID.
Definition Process.hpp:298
static int Kill(int pid, int signum) noexcept
Sends the specified signal to the given PID.
Definition Process.hpp:292
static Option Env(std::string_view env)
Set environment variable for the subprocess.
Definition Process.hpp:102
static Option SetFlags(unsigned int flags)
Set spawn flags.
Definition Process.hpp:144
static Option StdioInherit(size_t index, Pipe &pipe)
Inherit a pipe from the parent process.
Definition Process.hpp:187
static std::shared_ptr< Process > SpawnArray(Loop &loop, std::string_view file, std::initializer_list< Option > options)
Definition Process.hpp:236
static std::shared_ptr< Process > Spawn(const std::shared_ptr< Loop > &loop, std::string_view file, const Args &... options)
Definition Process.hpp:274
static Option StdioInherit(size_t index, int fd)
Inherit a file descriptor from the parent process.
Definition Process.hpp:175
static Option Cwd(std::string_view cwd)
Set the current working directory for the subprocess.
Definition Process.hpp:113
static Option ClearFlags(unsigned int flags)
Clear spawn flags.
Definition Process.hpp:154
Definition BooleanTopic.hpp:24
Definition Prepare.hpp:14
flags
Definition http_parser.hpp:206
SignalBase< detail::NullMutex, T... > Signal
Specialization of SignalBase to be used in single threaded contexts.
Definition Signal.h:809
int pid
Definition uv.h:1144
Structure for Spawn() option temporaries.
Definition Process.hpp:41
Option(const wpi::util::SmallVectorImpl< char > &arg)
Definition Process.hpp:72
Option(Type type)
Definition Process.hpp:77
Type
Definition Process.hpp:42
@ kCwd
Definition Process.hpp:46
@ kUid
Definition Process.hpp:47
@ kStdioInheritFd
Definition Process.hpp:52
@ kStdioInheritPipe
Definition Process.hpp:53
@ kGid
Definition Process.hpp:48
@ kStdioCreatePipe
Definition Process.hpp:54
@ kEnv
Definition Process.hpp:45
@ kSetFlags
Definition Process.hpp:49
@ kClearFlags
Definition Process.hpp:50
@ kNone
Definition Process.hpp:43
@ kArg
Definition Process.hpp:44
@ kStdioIgnore
Definition Process.hpp:51
const char * str
Definition Process.hpp:82
Option()
Definition Process.hpp:57
Pipe * pipe
Definition Process.hpp:90
Type m_type
Definition Process.hpp:79
union wpi::net::uv::Process::Option::@071353211124055204151244037274343020353135212202 m_data
Option(const std::string &arg)
Definition Process.hpp:63
std::string m_strData
Definition Process.hpp:80
struct wpi::net::uv::Process::Option::@071353211124055204151244037274343020353135212202::@123141332073265301115027032264254307124073022137 stdio
size_t index
Definition Process.hpp:87
uv_gid_t gid
Definition Process.hpp:84
Option(std::string_view arg)
Definition Process.hpp:67
int fd
Definition Process.hpp:89
Option(const char *arg)
Definition Process.hpp:59
unsigned int flags
Definition Process.hpp:85
uv_uid_t uid
Definition Process.hpp:83
UV_EXTERN int uv_process_kill(uv_process_t *, int signum)
UV_EXTERN int uv_kill(int pid, int signum)
UV_EXTERN void uv_disable_stdio_inheritance(void)