chigraph  master
Systems programming language written for beginners in LLVM
Subprocess.hpp
Go to the documentation of this file.
1 
3 #pragma once
4 
5 #ifndef CHI_SUBPROCESS_HPP
6 #define CHI_SUBPROCESS_HPP
7 
8 #include "chi/Support/Fwd.hpp"
9 
10 #include <boost/filesystem/operations.hpp>
11 #include <boost/filesystem/path.hpp>
12 #include <boost/optional.hpp>
13 
14 #include <chrono>
15 #include <string>
16 #include <vector>
17 
18 namespace chi {
19 
52 struct Subprocess {
54  using pipeHandler = std::function<void(const char* data, size_t size)>;
55 
58  Subprocess(const boost::filesystem::path& pathToExecutable);
59 
61  ~Subprocess();
62 
68 
74  template <typename ForwardIterator>
75  void setArguments(const ForwardIterator& begin, const ForwardIterator& end) {
76  // make sure the iterator type is good to go
77  static_assert(
78  std::is_convertible<typename std::iterator_traits<ForwardIterator>::value_type,
79  std::string>::value,
80  "Cannot run setArguments with iterators not convertable to std::string");
81 
82  assert(!started() && "Cannot set arguments after start() has been called");
83 
84  mArguments = std::vector<std::string>(begin, end);
85  }
86 
90  template <typename Range>
91  void setArguments(Range&& range) {
92  setArguments(std::forward<Range>(range).begin(), std::forward<Range>(range).end());
93  }
94 
98  void setArguments(std::initializer_list<const char*> init) {
99  setArguments(init.begin(), init.end());
100  }
101 
104  const std::vector<std::string>& arguments() const { return mArguments; }
105 
111  void attachToStdOut(pipeHandler stdOutHandler) {
112  assert(!started() &&
113  "Cannot attach a differnt function to stdout after start() has been called");
114  mStdOutHandler = stdOutHandler;
115  }
116 
122  void attachToStdErr(pipeHandler stdErrHandler) {
123  assert(!started() &&
124  "Cannot attach a differnt function to stderr after start() has been called");
125  mStdErrHandler = stdErrHandler;
126  }
127 
135  void attachStringToStdOut(std::string& str) {
136  attachToStdOut([&str](const char* data, size_t size) { str.append(data, size); });
137  }
138 
146  void attachStringToStdErr(std::string& str) {
147  attachToStdErr([&str](const char* data, size_t size) { str.append(data, size); });
148  }
149 
153  void setWorkingDirectory(boost::filesystem::path newWd) { mWorkingDir = std::move(newWd); }
154 
156 
162  Result start();
163 
166  bool started() const { return mStarted; }
167 
171 
177  Result pushToStdIn(const char* data, size_t size);
178 
184  Result closeStdIn();
185 
188  bool isStdInClosed() const { return mStdInClosed; }
189 
193  void kill();
194 
197  void wait();
198 
202  int exitCode();
203 
207  bool running();
208 
210 
211 private:
212  struct Implementation;
213  std::unique_ptr<Implementation> mPimpl;
214 
215  std::vector<std::string> mArguments;
216 
217  pipeHandler mStdOutHandler;
218  pipeHandler mStdErrHandler;
219 
220  boost::filesystem::path mExePath;
221 
222  boost::filesystem::path mWorkingDir = boost::filesystem::current_path();
223 
224  bool mStarted = false;
225  bool mStdInClosed = false;
226 
227  boost::optional<int> mExitCode;
228 };
229 
231 
232 } // namespace chi
233 
234 #endif // CHI_SUBPROCESS_HPP
void attachStringToStdOut(std::string &str)
Attach a string to stdout.
Definition: Subprocess.hpp:135
~Subprocess()
Wait for the process to exit and close all open handles.
Definition: Subprocess.cpp:353
void wait()
Wait for the process to complete.
Definition: Subprocess.cpp:525
void attachToStdOut(pipeHandler stdOutHandler)
Attach a function handler to the child stdout.
Definition: Subprocess.hpp:111
int exitCode()
Wait and gets the exit code.
Definition: Subprocess.cpp:534
void attachStringToStdErr(std::string &str)
Attach a string to stderr.
Definition: Subprocess.hpp:146
const std::vector< std::string > & arguments() const
Get the currently set arguments for the program.
Definition: Subprocess.hpp:104
void attachToStdErr(pipeHandler stdErrHandler)
Attach a function handler to the child stderr.
Definition: Subprocess.hpp:122
Result closeStdIn()
Close the STDIN stream (send an EOF)
Definition: Subprocess.cpp:388
Subprocess(const boost::filesystem::path &pathToExecutable)
Construct a Subprocess with a path to an executable.
Definition: Subprocess.cpp:572
bool isStdInClosed() const
Checks if the stdin is closed.
Definition: Subprocess.hpp:188
Result pushToStdIn(const char *data, size_t size)
Pushes data to the stdin stream of the child process.
Definition: Subprocess.cpp:374
Provides an platform-independent abstraction for creating subprocesses.
Definition: Subprocess.hpp:52
bool running()
Check if the process is still running.
Definition: Subprocess.cpp:550
Result start()
Start the process.
Definition: Subprocess.cpp:405
void setArguments(const ForwardIterator &begin, const ForwardIterator &end)
Set the arguments for the program with a begin and end iterator.
Definition: Subprocess.hpp:75
void kill()
Kill the child process On POSIX, this sends SIGINT.
Definition: Subprocess.cpp:520
void setArguments(Range &&range)
Set the arguments for the program with a range.
Definition: Subprocess.hpp:91
void setWorkingDirectory(boost::filesystem::path newWd)
Set the working directory of the process.
Definition: Subprocess.hpp:153
bool started() const
Check if the child has started (start() has been called)
Definition: Subprocess.hpp:166
The namespace where chigraph lives.
void setArguments(std::initializer_list< const char *> init)
Set the arguments for the program with an initializer_list.
Definition: Subprocess.hpp:98
The result object, used for identifiying errors with good diagnostics.
Definition: Result.hpp:72
std::function< void(const char *data, size_t size)> pipeHandler
The function type for recieving data from pipes.
Definition: Subprocess.hpp:54