WPILibC++  2020.3.2
Process.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef WPIUTIL_WPI_UV_PROCESS_H_
9 #define WPIUTIL_WPI_UV_PROCESS_H_
10 
11 #include <uv.h>
12 
13 #include <initializer_list>
14 #include <memory>
15 #include <string>
16 
17 #include "wpi/ArrayRef.h"
18 #include "wpi/Signal.h"
19 #include "wpi/SmallVector.h"
20 #include "wpi/Twine.h"
21 #include "wpi/uv/Handle.h"
22 
23 namespace wpi {
24 namespace uv {
25 
26 class Loop;
27 class Pipe;
28 
34 class Process final : public HandleImpl<Process, uv_process_t> {
35  struct private_init {};
36 
37  public:
38  explicit Process(const private_init&) {}
39  ~Process() noexcept override = default;
40 
46  struct Option {
47  enum Type {
48  kNone,
49  kArg,
50  kEnv,
51  kCwd,
52  kUid,
53  kGid,
54  kSetFlags,
55  kClearFlags,
56  kStdioIgnore,
57  kStdioInheritFd,
58  kStdioInheritPipe,
59  kStdioCreatePipe
60  };
61 
62  Option() : m_type(kNone) {}
63 
64  /*implicit*/ Option(const char* arg) { // NOLINT(runtime/explicit)
65  m_data.str = arg;
66  }
67 
68  /*implicit*/ Option(const std::string& arg) { // NOLINT(runtime/explicit)
69  m_data.str = arg.data();
70  }
71 
72  /*implicit*/ Option(StringRef arg) // NOLINT(runtime/explicit)
73  : m_strData(arg) {
74  m_data.str = m_strData.c_str();
75  }
76 
77  /*implicit*/ Option(
78  const SmallVectorImpl<char>& arg) // NOLINT(runtime/explicit)
79  : m_strData(arg.data(), arg.size()) {
80  m_data.str = m_strData.c_str();
81  }
82 
83  /*implicit*/ Option(const Twine& arg) // NOLINT(runtime/explicit)
84  : m_strData(arg.str()) {
85  m_data.str = m_strData.c_str();
86  }
87 
88  explicit Option(Type type) : m_type(type) {}
89 
90  Type m_type = kArg;
91  std::string m_strData;
92  union {
93  const char* str;
94  uv_uid_t uid;
95  uv_gid_t gid;
96  unsigned int flags;
97  struct {
98  size_t index;
99  union {
100  int fd;
101  Pipe* pipe;
102  };
103  unsigned int flags;
104  } stdio;
105  } m_data;
106  };
107 
113  static Option Env(const Twine& env) {
114  Option o(Option::kEnv);
115  o.m_strData = env.str();
116  o.m_data.str = o.m_strData.c_str();
117  return o;
118  }
119 
124  static Option Cwd(const Twine& cwd) {
125  Option o(Option::kCwd);
126  o.m_strData = cwd.str();
127  o.m_data.str = o.m_strData.c_str();
128  return o;
129  }
130 
135  static Option Uid(uv_uid_t uid) {
136  Option o(Option::kUid);
137  o.m_data.uid = uid;
138  return o;
139  }
140 
145  static Option Gid(uv_gid_t gid) {
146  Option o(Option::kGid);
147  o.m_data.gid = gid;
148  return o;
149  }
150 
155  static Option SetFlags(unsigned int flags) {
156  Option o(Option::kSetFlags);
157  o.m_data.flags = flags;
158  return o;
159  }
160 
165  static Option ClearFlags(unsigned int flags) {
166  Option o(Option::kClearFlags);
167  o.m_data.flags = flags;
168  return o;
169  }
170 
175  static Option StdioIgnore(size_t index) {
176  Option o(Option::kStdioIgnore);
177  o.m_data.stdio.index = index;
178  return o;
179  }
180 
186  static Option StdioInherit(size_t index, int fd) {
187  Option o(Option::kStdioInheritFd);
188  o.m_data.stdio.index = index;
189  o.m_data.stdio.fd = fd;
190  return o;
191  }
192 
198  static Option StdioInherit(size_t index, Pipe& pipe) {
199  Option o(Option::kStdioInheritPipe);
200  o.m_data.stdio.index = index;
201  o.m_data.stdio.pipe = &pipe;
202  return o;
203  }
204 
212  static Option StdioCreatePipe(size_t index, Pipe& pipe, unsigned int flags) {
213  Option o(Option::kStdioCreatePipe);
214  o.m_data.stdio.index = index;
215  o.m_data.stdio.pipe = &pipe;
216  o.m_data.stdio.flags = flags;
217  return o;
218  }
219 
229  static void DisableStdioInheritance() { uv_disable_stdio_inheritance(); }
230 
244  static std::shared_ptr<Process> SpawnArray(Loop& loop, const Twine& file,
245  ArrayRef<Option> options);
246 
247  static std::shared_ptr<Process> SpawnArray(
248  Loop& loop, const Twine& file, std::initializer_list<Option> options) {
249  return SpawnArray(loop, file, makeArrayRef(options.begin(), options.end()));
250  }
251 
252  template <typename... Args>
253  static std::shared_ptr<Process> Spawn(Loop& loop, const Twine& file,
254  const Args&... options) {
255  return SpawnArray(loop, file, {options...});
256  }
257 
271  static std::shared_ptr<Process> SpawnArray(const std::shared_ptr<Loop>& loop,
272  const Twine& file,
273  ArrayRef<Option> options) {
274  return SpawnArray(*loop, file, options);
275  }
276 
277  static std::shared_ptr<Process> SpawnArray(
278  const std::shared_ptr<Loop>& loop, const Twine& file,
279  std::initializer_list<Option> options) {
280  return SpawnArray(*loop, file, options);
281  }
282 
283  template <typename... Args>
284  static std::shared_ptr<Process> Spawn(const std::shared_ptr<Loop>& loop,
285  const Twine& file,
286  const Args&... options) {
287  return SpawnArray(*loop, file, {options...});
288  }
289 
294  void Kill(int signum) { Invoke(&uv_process_kill, GetRaw(), signum); }
295 
302  static int Kill(int pid, int signum) noexcept { return uv_kill(pid, signum); }
303 
308  uv_pid_t GetPid() const noexcept { return GetRaw()->pid; }
309 
315 };
316 
317 } // namespace uv
318 } // namespace wpi
319 
320 #endif // WPIUTIL_WPI_UV_PROCESS_H_
wpi::uv::HandleImpl< Process, uv_process_t >::GetRaw
uv_process_t * GetRaw() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:288
wpi::uv::Process::Gid
static Option Gid(uv_gid_t gid)
Set the child process' group id.
Definition: Process.h:145
wpi::uv::Process::GetPid
uv_pid_t GetPid() const noexcept
Get the process ID.
Definition: Process.h:308
wpi::uv::Process::Kill
static int Kill(int pid, int signum) noexcept
Sends the specified signal to the given PID.
Definition: Process.h:302
wpi::uv::Process::StdioCreatePipe
static Option StdioCreatePipe(size_t index, Pipe &pipe, unsigned int flags)
Create a pipe between the child and the parent.
Definition: Process.h:212
wpi::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:42
wpi::SmallVectorImpl< char >
wpi::uv::Process::DisableStdioInheritance
static void DisableStdioInheritance()
Disables inheritance for file descriptors / handles that this process inherited from its parent.
Definition: Process.h:229
wpi::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:447
wpi::uv::Process::Env
static Option Env(const Twine &env)
Set environment variable for the subprocess.
Definition: Process.h:113
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: EventLoopRunner.h:17
wpi::uv::Process::exited
sig::Signal< int64_t, int > exited
Signal generated when the process exits.
Definition: Process.h:314
wpi::SmallVectorTemplateCommon::data
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:158
wpi::uv::Process::ClearFlags
static Option ClearFlags(unsigned int flags)
Clear spawn flags.
Definition: Process.h:165
wpi::uv::Process::Option
Structure for Spawn() option temporaries.
Definition: Process.h:46
wpi::uv::Process::StdioIgnore
static Option StdioIgnore(size_t index)
Explicitly ignore a stdio.
Definition: Process.h:175
wpi::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
wpi::uv::Process::SpawnArray
static std::shared_ptr< Process > SpawnArray(const std::shared_ptr< Loop > &loop, const Twine &file, ArrayRef< Option > options)
Starts a process.
Definition: Process.h:271
wpi::uv::HandleImpl
Handle.
Definition: Handle.h:273
wpi::uv::Process::SetFlags
static Option SetFlags(unsigned int flags)
Set spawn flags.
Definition: Process.h:155
wpi::uv::Process::StdioInherit
static Option StdioInherit(size_t index, Pipe &pipe)
Inherit a pipe from the parent process.
Definition: Process.h:198
wpi::uv::Process::Uid
static Option Uid(uv_uid_t uid)
Set the child process' user id.
Definition: Process.h:135
wpi::uv::Pipe
Pipe handle.
Definition: Pipe.h:31
wpi::Twine::str
std::string str() const
Return the twine contents as a std::string.
wpi::uv::Process::SpawnArray
static std::shared_ptr< Process > SpawnArray(Loop &loop, const Twine &file, ArrayRef< Option > options)
Starts a process.
wpi::uv::Loop
Event loop.
Definition: Loop.h:39
wpi::uv::Process::StdioInherit
static Option StdioInherit(size_t index, int fd)
Inherit a file descriptor from the parent process.
Definition: Process.h:186
wpi::uv::Process
Process handle.
Definition: Process.h:34
wpi::uv::Process::Cwd
static Option Cwd(const Twine &cwd)
Set the current working directory for the subprocess.
Definition: Process.h:124
wpi::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:85
wpi::sig::SignalBase
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495
wpi::uv::Process::Kill
void Kill(int signum)
Sends the specified signal to the process.
Definition: Process.h:294