WPILibC++  2019.1.1-beta-4-32-g6bdd7ce
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Process.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2018 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 <memory>
14 #include <string>
15 
16 #include "wpi/ArrayRef.h"
17 #include "wpi/Signal.h"
18 #include "wpi/SmallVector.h"
19 #include "wpi/Twine.h"
20 #include "wpi/uv/Handle.h"
21 
22 namespace wpi {
23 namespace uv {
24 
25 class Loop;
26 class Pipe;
27 
33 class Process final : public HandleImpl<Process, uv_process_t> {
34  struct private_init {};
35 
36  public:
37  explicit Process(const private_init&) {}
38  ~Process() noexcept override = default;
39 
45  struct Option {
46  enum Type {
47  kNone,
48  kArg,
49  kEnv,
50  kCwd,
51  kUid,
52  kGid,
53  kSetFlags,
54  kClearFlags,
55  kStdioIgnore,
56  kStdioInheritFd,
57  kStdioInheritPipe,
58  kStdioCreatePipe
59  };
60 
61  Option() : m_type(kNone) {}
62 
63  /*implicit*/ Option(const char* arg) { // NOLINT(runtime/explicit)
64  m_data.str = arg;
65  }
66 
67  /*implicit*/ Option(const std::string& arg) { // NOLINT(runtime/explicit)
68  m_data.str = arg.data();
69  }
70 
71  /*implicit*/ Option(StringRef arg) // NOLINT(runtime/explicit)
72  : m_strData(arg) {
73  m_data.str = m_strData.c_str();
74  }
75 
76  /*implicit*/ Option(
77  const SmallVectorImpl<char>& arg) // NOLINT(runtime/explicit)
78  : m_strData(arg.data(), arg.size()) {
79  m_data.str = m_strData.c_str();
80  }
81 
82  /*implicit*/ Option(const Twine& arg) // NOLINT(runtime/explicit)
83  : m_strData(arg.str()) {
84  m_data.str = m_strData.c_str();
85  }
86 
87  explicit Option(Type type) : m_type(type) {}
88 
89  Type m_type = kArg;
90  std::string m_strData;
91  union {
92  const char* str;
93  uv_uid_t uid;
94  uv_gid_t gid;
95  unsigned int flags;
96  struct {
97  size_t index;
98  union {
99  int fd;
100  Pipe* pipe;
101  };
102  unsigned int flags;
103  } stdio;
104  } m_data;
105  };
106 
112  static Option Env(const Twine& env) {
113  Option o(Option::kEnv);
114  o.m_strData = env.str();
115  o.m_data.str = o.m_strData.c_str();
116  return o;
117  }
118 
123  static Option Cwd(const Twine& cwd) {
124  Option o(Option::kCwd);
125  o.m_strData = cwd.str();
126  o.m_data.str = o.m_strData.c_str();
127  return o;
128  }
129 
134  static Option Uid(uv_uid_t uid) {
135  Option o(Option::kUid);
136  o.m_data.uid = uid;
137  return o;
138  }
139 
144  static Option Gid(uv_gid_t gid) {
145  Option o(Option::kGid);
146  o.m_data.gid = gid;
147  return o;
148  }
149 
154  static Option SetFlags(unsigned int flags) {
155  Option o(Option::kSetFlags);
156  o.m_data.flags = flags;
157  return o;
158  }
159 
164  static Option ClearFlags(unsigned int flags) {
165  Option o(Option::kClearFlags);
166  o.m_data.flags = flags;
167  return o;
168  }
169 
174  static Option StdioIgnore(size_t index) {
175  Option o(Option::kStdioIgnore);
176  o.m_data.stdio.index = index;
177  return o;
178  }
179 
185  static Option StdioInherit(size_t index, int fd) {
186  Option o(Option::kStdioInheritFd);
187  o.m_data.stdio.index = index;
188  o.m_data.stdio.fd = fd;
189  return o;
190  }
191 
197  static Option StdioInherit(size_t index, Pipe& pipe) {
198  Option o(Option::kStdioInheritPipe);
199  o.m_data.stdio.index = index;
200  o.m_data.stdio.pipe = &pipe;
201  return o;
202  }
203 
211  static Option StdioCreatePipe(size_t index, Pipe& pipe, unsigned int flags) {
212  Option o(Option::kStdioCreatePipe);
213  o.m_data.stdio.index = index;
214  o.m_data.stdio.pipe = &pipe;
215  o.m_data.stdio.flags = flags;
216  return o;
217  }
218 
228  static void DisableStdioInheritance() { uv_disable_stdio_inheritance(); }
229 
243  static std::shared_ptr<Process> SpawnArray(Loop& loop, const Twine& file,
244  ArrayRef<Option> options);
245 
246  template <typename... Args>
247  static std::shared_ptr<Process> Spawn(Loop& loop, const Twine& file,
248  const Args&... options) {
249  return SpawnArray(loop, file, {options...});
250  }
251 
265  static std::shared_ptr<Process> SpawnArray(const std::shared_ptr<Loop>& loop,
266  const Twine& file,
267  ArrayRef<Option> options) {
268  return SpawnArray(*loop, file, options);
269  }
270 
271  template <typename... Args>
272  static std::shared_ptr<Process> Spawn(const std::shared_ptr<Loop>& loop,
273  const Twine& file,
274  const Args&... options) {
275  return SpawnArray(*loop, file, {options...});
276  }
277 
282  void Kill(int signum) { Invoke(&uv_process_kill, GetRaw(), signum); }
283 
290  static int Kill(int pid, int signum) noexcept { return uv_kill(pid, signum); }
291 
296  uv_pid_t GetPid() const noexcept { return GetRaw()->pid; }
297 
303 };
304 
305 } // namespace uv
306 } // namespace wpi
307 
308 #endif // WPIUTIL_WPI_UV_PROCESS_H_
uv_pid_t GetPid() const noexcept
Get the process ID.
Definition: Process.h:296
uv_process_t * GetRaw() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:264
static Option Gid(uv_gid_t gid)
Set the child process' group id.
Definition: Process.h:144
Handle.
Definition: Handle.h:249
static int Kill(int pid, int signum) noexcept
Sends the specified signal to the given PID.
Definition: Process.h:290
static void DisableStdioInheritance()
Disables inheritance for file descriptors / handles that this process inherited from its parent...
Definition: Process.h:228
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:41
Structure for Spawn() option temporaries.
Definition: Process.h:45
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
static Option StdioCreatePipe(size_t index, Pipe &pipe, unsigned int flags)
Create a pipe between the child and the parent.
Definition: Process.h:211
sig::Signal< int64_t, int > exited
Signal generated when the process exits.
Definition: Process.h:302
Process handle.
Definition: Process.h:33
static std::shared_ptr< Process > SpawnArray(const std::shared_ptr< Loop > &loop, const Twine &file, ArrayRef< Option > options)
Starts a process.
Definition: Process.h:265
static Option Env(const Twine &env)
Set environment variable for the subprocess.
Definition: Process.h:112
Pipe handle.
Definition: Pipe.h:31
static Option StdioIgnore(size_t index)
Explicitly ignore a stdio.
Definition: Process.h:174
static Option ClearFlags(unsigned int flags)
Clear spawn flags.
Definition: Process.h:164
std::string str() const
Return the twine contents as a std::string.
static Option SetFlags(unsigned int flags)
Set spawn flags.
Definition: Process.h:154
static std::shared_ptr< Process > SpawnArray(Loop &loop, const Twine &file, ArrayRef< Option > options)
Starts a process.
Event loop.
Definition: Loop.h:39
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static Option Uid(uv_uid_t uid)
Set the child process' user id.
Definition: Process.h:134
static Option StdioInherit(size_t index, Pipe &pipe)
Inherit a pipe from the parent process.
Definition: Process.h:197
void Kill(int signum)
Sends the specified signal to the process.
Definition: Process.h:282
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495
static Option Cwd(const Twine &cwd)
Set the current working directory for the subprocess.
Definition: Process.h:123
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:151
static Option StdioInherit(size_t index, int fd)
Inherit a file descriptor from the parent process.
Definition: Process.h:185