Bitcoin Core  27.99.0
P2P Digital Currency
subprocess.hpp
Go to the documentation of this file.
1 // Based on the https://github.com/arun11299/cpp-subprocess project.
2 
36 #ifndef SUBPROCESS_HPP
37 #define SUBPROCESS_HPP
38 
39 #include <algorithm>
40 #include <cassert>
41 #include <csignal>
42 #include <cstdio>
43 #include <cstdlib>
44 #include <cstring>
45 #include <exception>
46 #include <future>
47 #include <initializer_list>
48 #include <iostream>
49 #include <locale>
50 #include <map>
51 #include <memory>
52 #include <sstream>
53 #include <string>
54 #include <vector>
55 
56 #if (defined _MSC_VER) || (defined __MINGW32__)
57  #define __USING_WINDOWS__
58 #endif
59 
60 #ifdef __USING_WINDOWS__
61  #include <codecvt>
62 #endif
63 
64 extern "C" {
65 #ifdef __USING_WINDOWS__
66  #include <Windows.h>
67  #include <io.h>
68  #include <cwchar>
69 
70  #define close _close
71  #define open _open
72  #define fileno _fileno
73 #else
74  #include <sys/wait.h>
75  #include <unistd.h>
76 #endif
77  #include <csignal>
78  #include <fcntl.h>
79  #include <sys/types.h>
80 }
81 
105 namespace subprocess {
106 
107 // Max buffer size allocated on stack for read error
108 // from pipe
109 static const size_t SP_MAX_ERR_BUF_SIZ = 1024;
110 
111 // Default buffer capacity for OutBuffer and ErrBuffer.
112 // If the data exceeds this capacity, the buffer size is grown
113 // by 1.5 times its previous capacity
114 static const size_t DEFAULT_BUF_CAP_BYTES = 8192;
115 
116 
117 /*-----------------------------------------------
118  * EXCEPTION CLASSES
119  *-----------------------------------------------
120  */
121 
129 class CalledProcessError: public std::runtime_error
130 {
131 public:
132  int retcode;
133  CalledProcessError(const std::string& error_msg, int retcode):
134  std::runtime_error(error_msg), retcode(retcode)
135  {}
136 };
137 
138 
149 class OSError: public std::runtime_error
150 {
151 public:
152  OSError(const std::string& err_msg, int err_code):
153  std::runtime_error( err_msg + ": " + std::strerror(err_code) )
154  {}
155 };
156 
157 //--------------------------------------------------------------------
158 namespace util
159 {
160  template <typename R>
161  inline bool is_ready(std::shared_future<R> const &f)
162  {
163  return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
164  }
165 
166  inline void quote_argument(const std::wstring &argument, std::wstring &command_line,
167  bool force)
168  {
169  //
170  // Unless we're told otherwise, don't quote unless we actually
171  // need to do so --- hopefully avoid problems if programs won't
172  // parse quotes properly
173  //
174 
175  if (force == false && argument.empty() == false &&
176  argument.find_first_of(L" \t\n\v\"") == argument.npos) {
177  command_line.append(argument);
178  }
179  else {
180  command_line.push_back(L'"');
181 
182  for (auto it = argument.begin();; ++it) {
183  unsigned number_backslashes = 0;
184 
185  while (it != argument.end() && *it == L'\\') {
186  ++it;
187  ++number_backslashes;
188  }
189 
190  if (it == argument.end()) {
191 
192  //
193  // Escape all backslashes, but let the terminating
194  // double quotation mark we add below be interpreted
195  // as a metacharacter.
196  //
197 
198  command_line.append(number_backslashes * 2, L'\\');
199  break;
200  }
201  else if (*it == L'"') {
202 
203  //
204  // Escape all backslashes and the following
205  // double quotation mark.
206  //
207 
208  command_line.append(number_backslashes * 2 + 1, L'\\');
209  command_line.push_back(*it);
210  }
211  else {
212 
213  //
214  // Backslashes aren't special here.
215  //
216 
217  command_line.append(number_backslashes, L'\\');
218  command_line.push_back(*it);
219  }
220  }
221 
222  command_line.push_back(L'"');
223  }
224  }
225 
226 #ifdef __USING_WINDOWS__
227  inline std::string get_last_error(DWORD errorMessageID)
228  {
229  if (errorMessageID == 0)
230  return std::string();
231 
232  LPSTR messageBuffer = nullptr;
233  size_t size = FormatMessageA(
234  FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
235  FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
236  NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
237  (LPSTR)&messageBuffer, 0, NULL);
238 
239  std::string message(messageBuffer, size);
240 
241  LocalFree(messageBuffer);
242 
243  return message;
244  }
245 
246  inline FILE *file_from_handle(HANDLE h, const char *mode)
247  {
248  int md;
249  if (!mode) {
250  throw OSError("invalid_mode", 0);
251  }
252 
253  if (mode[0] == 'w') {
254  md = _O_WRONLY;
255  }
256  else if (mode[0] == 'r') {
257  md = _O_RDONLY;
258  }
259  else {
260  throw OSError("file_from_handle", 0);
261  }
262 
263  int os_fhandle = _open_osfhandle((intptr_t)h, md);
264  if (os_fhandle == -1) {
265  CloseHandle(h);
266  throw OSError("_open_osfhandle", 0);
267  }
268 
269  FILE *fp = _fdopen(os_fhandle, mode);
270  if (fp == 0) {
271  _close(os_fhandle);
272  throw OSError("_fdopen", 0);
273  }
274 
275  return fp;
276  }
277 
278  inline void configure_pipe(HANDLE* read_handle, HANDLE* write_handle, HANDLE* child_handle)
279  {
280  SECURITY_ATTRIBUTES saAttr;
281 
282  // Set the bInheritHandle flag so pipe handles are inherited.
283  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
284  saAttr.bInheritHandle = TRUE;
285  saAttr.lpSecurityDescriptor = NULL;
286 
287  // Create a pipe for the child process's STDIN.
288  if (!CreatePipe(read_handle, write_handle, &saAttr,0))
289  throw OSError("CreatePipe", 0);
290 
291  // Ensure the write handle to the pipe for STDIN is not inherited.
292  if (!SetHandleInformation(*child_handle, HANDLE_FLAG_INHERIT, 0))
293  throw OSError("SetHandleInformation", 0);
294  }
295 #endif
296 
306  static inline std::vector<std::string>
307  split(const std::string& str, const std::string& delims=" \t")
308  {
309  std::vector<std::string> res;
310  size_t init = 0;
311 
312  while (true) {
313  auto pos = str.find_first_of(delims, init);
314  if (pos == std::string::npos) {
315  res.emplace_back(str.substr(init, str.length()));
316  break;
317  }
318  res.emplace_back(str.substr(init, pos - init));
319  pos++;
320  init = pos;
321  }
322 
323  return res;
324  }
325 
326 
327 #ifndef __USING_WINDOWS__
337  static inline
338  void set_clo_on_exec(int fd, bool set = true)
339  {
340  int flags = fcntl(fd, F_GETFD, 0);
341  if (set) flags |= FD_CLOEXEC;
342  else flags &= ~FD_CLOEXEC;
343  //TODO: should check for errors
344  fcntl(fd, F_SETFD, flags);
345  }
346 
347 
357  static inline
358  std::pair<int, int> pipe_cloexec() noexcept(false)
359  {
360  int pipe_fds[2];
361  int res = pipe(pipe_fds);
362  if (res) {
363  throw OSError("pipe failure", errno);
364  }
365 
366  set_clo_on_exec(pipe_fds[0]);
367  set_clo_on_exec(pipe_fds[1]);
368 
369  return std::make_pair(pipe_fds[0], pipe_fds[1]);
370  }
371 #endif
372 
373 
385  static inline
386  int write_n(int fd, const char* buf, size_t length)
387  {
388  size_t nwritten = 0;
389  while (nwritten < length) {
390  int written = write(fd, buf + nwritten, length - nwritten);
391  if (written == -1) return -1;
392  nwritten += written;
393  }
394  return nwritten;
395  }
396 
397 
412  static inline
413  int read_atmost_n(FILE* fp, char* buf, size_t read_upto)
414  {
415 #ifdef __USING_WINDOWS__
416  return (int)fread(buf, 1, read_upto, fp);
417 #else
418  int fd = fileno(fp);
419  int rbytes = 0;
420  int eintr_cnter = 0;
421 
422  while (1) {
423  int read_bytes = read(fd, buf + rbytes, read_upto - rbytes);
424  if (read_bytes == -1) {
425  if (errno == EINTR) {
426  if (eintr_cnter >= 50) return -1;
427  eintr_cnter++;
428  continue;
429  }
430  return -1;
431  }
432  if (read_bytes == 0) return rbytes;
433 
434  rbytes += read_bytes;
435  }
436  return rbytes;
437 #endif
438  }
439 
440 
454  static inline int read_all(FILE* fp, std::vector<char>& buf)
455  {
456  auto buffer = buf.data();
457  int total_bytes_read = 0;
458  int fill_sz = buf.size();
459 
460  while (1) {
461  const int rd_bytes = read_atmost_n(fp, buffer, fill_sz);
462 
463  if (rd_bytes == -1) { // Read finished
464  if (total_bytes_read == 0) return -1;
465  break;
466 
467  } else if (rd_bytes == fill_sz) { // Buffer full
468  const auto orig_sz = buf.size();
469  const auto new_sz = orig_sz * 2;
470  buf.resize(new_sz);
471  fill_sz = new_sz - orig_sz;
472 
473  //update the buffer pointer
474  buffer = buf.data();
475  total_bytes_read += rd_bytes;
476  buffer += total_bytes_read;
477 
478  } else { // Partial data ? Continue reading
479  total_bytes_read += rd_bytes;
480  fill_sz -= rd_bytes;
481  break;
482  }
483  }
484  buf.erase(buf.begin()+total_bytes_read, buf.end()); // remove extra nulls
485  return total_bytes_read;
486  }
487 
488 #ifndef __USING_WINDOWS__
502  static inline
503  std::pair<int, int> wait_for_child_exit(int pid)
504  {
505  int status = 0;
506  int ret = -1;
507  while (1) {
508  ret = waitpid(pid, &status, 0);
509  if (ret == -1) break;
510  if (ret == 0) continue;
511  return std::make_pair(ret, status);
512  }
513 
514  return std::make_pair(ret, status);
515  }
516 #endif
517 
518 } // end namespace util
519 
520 
521 
522 /* -------------------------------
523  * Popen Arguments
524  * -------------------------------
525  */
526 
531 {
532  string_arg(const char* arg): arg_value(arg) {}
533  string_arg(std::string&& arg): arg_value(std::move(arg)) {}
534  string_arg(std::string arg): arg_value(std::move(arg)) {}
535  std::string arg_value;
536 };
537 
547 {
548  template <typename T>
549  executable(T&& arg): string_arg(std::forward<T>(arg)) {}
550 };
551 
555 enum IOTYPE {
556  STDOUT = 1,
559 };
560 
561 //TODO: A common base/interface for below stream structures ??
562 
574 struct input
575 {
576  // For an already existing file descriptor.
577  explicit input(int fd): rd_ch_(fd) {}
578 
579  // FILE pointer.
580  explicit input (FILE* fp):input(fileno(fp)) { assert(fp); }
581 
582  explicit input(const char* filename) {
583  int fd = open(filename, O_RDONLY);
584  if (fd == -1) throw OSError("File not found: ", errno);
585  rd_ch_ = fd;
586  }
587  explicit input(IOTYPE typ) {
588  assert (typ == PIPE && "STDOUT/STDERR not allowed");
589 #ifndef __USING_WINDOWS__
590  std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
591 #endif
592  }
593 
594  int rd_ch_ = -1;
595  int wr_ch_ = -1;
596 };
597 
598 
609 struct output
610 {
611  explicit output(int fd): wr_ch_(fd) {}
612 
613  explicit output (FILE* fp):output(fileno(fp)) { assert(fp); }
614 
615  explicit output(const char* filename) {
616  int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
617  if (fd == -1) throw OSError("File not found: ", errno);
618  wr_ch_ = fd;
619  }
620  explicit output(IOTYPE typ) {
621  assert (typ == PIPE && "STDOUT/STDERR not allowed");
622 #ifndef __USING_WINDOWS__
623  std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
624 #endif
625  }
626 
627  int rd_ch_ = -1;
628  int wr_ch_ = -1;
629 };
630 
631 
640 struct error
641 {
642  explicit error(int fd): wr_ch_(fd) {}
643 
644  explicit error(FILE* fp):error(fileno(fp)) { assert(fp); }
645 
646  explicit error(const char* filename) {
647  int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
648  if (fd == -1) throw OSError("File not found: ", errno);
649  wr_ch_ = fd;
650  }
651  explicit error(IOTYPE typ) {
652  assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed");
653  if (typ == PIPE) {
654 #ifndef __USING_WINDOWS__
655  std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
656 #endif
657  } else {
658  // Need to defer it till we have checked all arguments
659  deferred_ = true;
660  }
661  }
662 
663  bool deferred_ = false;
664  int rd_ch_ = -1;
665  int wr_ch_ = -1;
666 };
667 
668 // ~~~~ End Popen Args ~~~~
669 
670 
682 class Buffer
683 {
684 public:
685  Buffer() {}
686  explicit Buffer(size_t cap) { buf.resize(cap); }
687  void add_cap(size_t cap) { buf.resize(cap); }
688 
689 #if 0
690  Buffer(const Buffer& other):
691  buf(other.buf),
692  length(other.length)
693  {
694  std::cout << "COPY" << std::endl;
695  }
696 
697  Buffer(Buffer&& other):
698  buf(std::move(other.buf)),
699  length(other.length)
700  {
701  std::cout << "MOVE" << std::endl;
702  }
703 #endif
704 
705 public:
706  std::vector<char> buf;
707  size_t length = 0;
708 };
709 
710 // Buffer for storing output written to output fd
712 // Buffer for storing output written to error fd
714 
715 
716 // Fwd Decl.
717 class Popen;
718 
719 /*---------------------------------------------------
720  * DETAIL NAMESPACE
721  *---------------------------------------------------
722  */
723 
724 namespace detail {
725 
726 // Metaprogram for searching a type within
727 // a variadic parameter pack
728 // This is particularly required to do a compile time
729 // checking of the arguments provided to 'check_output' function
730 // wherein the user is not expected to provide an 'output' option.
731 
732 template <typename... T> struct param_pack{};
733 
734 template <typename F, typename T> struct has_type;
735 
736 template <typename F>
737 struct has_type<F, param_pack<>> {
738  static constexpr bool value = false;
739 };
740 
741 template <typename F, typename... T>
742 struct has_type<F, param_pack<F, T...>> {
743  static constexpr bool value = true;
744 };
745 
746 template <typename F, typename H, typename... T>
747 struct has_type<F, param_pack<H,T...>> {
748  static constexpr bool value =
749  std::is_same<F, typename std::decay<H>::type>::value ? true : has_type<F, param_pack<T...>>::value;
750 };
751 
752 //----
753 
763 {
765 
766  void set_option(executable&& exe);
767  void set_option(input&& inp);
768  void set_option(output&& out);
769  void set_option(error&& err);
770 
771 private:
772  Popen* popen_ = nullptr;
773 };
774 
780 class Child
781 {
782 public:
783  Child(Popen* p, int err_wr_pipe):
784  parent_(p),
785  err_wr_pipe_(err_wr_pipe)
786  {}
787 
788  void execute_child();
789 
790 private:
791  // Lets call it parent even though
792  // technically a bit incorrect
793  Popen* parent_ = nullptr;
794  int err_wr_pipe_ = -1;
795 };
796 
797 // Fwd Decl.
798 class Streams;
799 
807 {
808 public:
809  Communication(Streams* stream): stream_(stream)
810  {}
811  void operator=(const Communication&) = delete;
812 public:
813  int send(const char* msg, size_t length);
814  int send(const std::vector<char>& msg);
815 
816  std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length);
817  std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
818  { return communicate(msg.data(), msg.size()); }
819 
820  void set_out_buf_cap(size_t cap) { out_buf_cap_ = cap; }
821  void set_err_buf_cap(size_t cap) { err_buf_cap_ = cap; }
822 
823 private:
824  std::pair<OutBuffer, ErrBuffer> communicate_threaded(
825  const char* msg, size_t length);
826 
827 private:
831 };
832 
833 
834 
844 class Streams
845 {
846 public:
847  Streams():comm_(this) {}
848  void operator=(const Streams&) = delete;
849 
850 public:
851  void setup_comm_channels();
852 
853  void cleanup_fds()
854  {
855  if (write_to_child_ != -1 && read_from_parent_ != -1) {
856  close(write_to_child_);
857  }
858  if (write_to_parent_ != -1 && read_from_child_ != -1) {
859  close(read_from_child_);
860  }
861  if (err_write_ != -1 && err_read_ != -1) {
862  close(err_read_);
863  }
864  }
865 
867  {
868  if (write_to_child_ != -1) close(write_to_child_);
869  if (read_from_child_ != -1) close(read_from_child_);
870  if (err_read_ != -1) close(err_read_);
871  }
872 
874  {
875  if (write_to_parent_ != -1) close(write_to_parent_);
876  if (read_from_parent_ != -1) close(read_from_parent_);
877  if (err_write_ != -1) close(err_write_);
878  }
879 
880  FILE* input() { return input_.get(); }
881  FILE* output() { return output_.get(); }
882  FILE* error() { return error_.get(); }
883 
884  void input(FILE* fp) { input_.reset(fp, fclose); }
885  void output(FILE* fp) { output_.reset(fp, fclose); }
886  void error(FILE* fp) { error_.reset(fp, fclose); }
887 
888  void set_out_buf_cap(size_t cap) { comm_.set_out_buf_cap(cap); }
889  void set_err_buf_cap(size_t cap) { comm_.set_err_buf_cap(cap); }
890 
891 public: /* Communication forwarding API's */
892  int send(const char* msg, size_t length)
893  { return comm_.send(msg, length); }
894 
895  int send(const std::vector<char>& msg)
896  { return comm_.send(msg); }
897 
898  std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
899  { return comm_.communicate(msg, length); }
900 
901  std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
902  { return comm_.communicate(msg); }
903 
904 
905 public:// Yes they are public
906 
907  std::shared_ptr<FILE> input_ = nullptr;
908  std::shared_ptr<FILE> output_ = nullptr;
909  std::shared_ptr<FILE> error_ = nullptr;
910 
911 #ifdef __USING_WINDOWS__
912  HANDLE g_hChildStd_IN_Rd = nullptr;
913  HANDLE g_hChildStd_IN_Wr = nullptr;
914  HANDLE g_hChildStd_OUT_Rd = nullptr;
915  HANDLE g_hChildStd_OUT_Wr = nullptr;
916  HANDLE g_hChildStd_ERR_Rd = nullptr;
917  HANDLE g_hChildStd_ERR_Wr = nullptr;
918 #endif
919 
920  // Pipes for communicating with child
921 
922  // Emulates stdin
923  int write_to_child_ = -1; // Parent owned descriptor
924  int read_from_parent_ = -1; // Child owned descriptor
925 
926  // Emulates stdout
927  int write_to_parent_ = -1; // Child owned descriptor
928  int read_from_child_ = -1; // Parent owned descriptor
929 
930  // Emulates stderr
931  int err_write_ = -1; // Write error to parent (Child owned)
932  int err_read_ = -1; // Read error from child (Parent owned)
933 
934 private:
936 };
937 
938 } // end namespace detail
939 
940 
941 
968 class Popen
969 {
970 public:
971  friend struct detail::ArgumentDeducer;
972  friend class detail::Child;
973 
974  template <typename... Args>
975  Popen(const std::string& cmd_args, Args&& ...args):
976  args_(cmd_args)
977  {
978  vargs_ = util::split(cmd_args);
979  init_args(std::forward<Args>(args)...);
980 
981  // Setup the communication channels of the Popen class
983 
984  execute_process();
985  }
986 
987  template <typename... Args>
988  Popen(std::initializer_list<const char*> cmd_args, Args&& ...args)
989  {
990  vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end());
991  init_args(std::forward<Args>(args)...);
992 
993  // Setup the communication channels of the Popen class
995 
996  execute_process();
997  }
998 
999  template <typename... Args>
1000  Popen(std::vector<std::string> vargs_, Args &&... args) : vargs_(vargs_)
1001  {
1002  init_args(std::forward<Args>(args)...);
1003 
1004  // Setup the communication channels of the Popen class
1006 
1007  execute_process();
1008  }
1009 
1010 /*
1011  ~Popen()
1012  {
1013 #ifdef __USING_WINDOWS__
1014  CloseHandle(this->process_handle_);
1015 #endif
1016  }
1017 */
1018 
1019  int pid() const noexcept { return child_pid_; }
1020 
1021  int retcode() const noexcept { return retcode_; }
1022 
1023  int wait() noexcept(false);
1024 
1025  int poll() noexcept(false);
1026 
1027  // Does not fail, Caller is expected to recheck the
1028  // status with a call to poll()
1029  void kill(int sig_num = 9);
1030 
1031  void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); }
1032 
1033  void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); }
1034 
1035  int send(const char* msg, size_t length)
1036  { return stream_.send(msg, length); }
1037 
1038  int send(const std::string& msg)
1039  { return send(msg.c_str(), msg.size()); }
1040 
1041  int send(const std::vector<char>& msg)
1042  { return stream_.send(msg); }
1043 
1044  std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
1045  {
1046  auto res = stream_.communicate(msg, length);
1047  retcode_ = wait();
1048  return res;
1049  }
1050 
1051  std::pair<OutBuffer, ErrBuffer> communicate(const std::string& msg)
1052  {
1053  return communicate(msg.c_str(), msg.size());
1054  }
1055 
1056  std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
1057  {
1058  auto res = stream_.communicate(msg);
1059  retcode_ = wait();
1060  return res;
1061  }
1062 
1063  std::pair<OutBuffer, ErrBuffer> communicate()
1064  {
1065  return communicate(nullptr, 0);
1066  }
1067 
1068  FILE* input() { return stream_.input(); }
1069  FILE* output() { return stream_.output();}
1070  FILE* error() { return stream_.error(); }
1071 
1073  void close_input() { stream_.input_.reset(); }
1074  void close_output() { stream_.output_.reset(); }
1075  void close_error() { stream_.error_.reset(); }
1076 
1077 private:
1078  template <typename F, typename... Args>
1079  void init_args(F&& farg, Args&&... args);
1080  void init_args();
1081  void populate_c_argv();
1082  void execute_process() noexcept(false);
1083 
1084 private:
1085  detail::Streams stream_;
1086 
1087 #ifdef __USING_WINDOWS__
1088  HANDLE process_handle_;
1089  std::future<void> cleanup_future_;
1090 #endif
1091 
1092  std::string exe_name_;
1093 
1094  // Command in string format
1095  std::string args_;
1096  // Command provided as sequence
1097  std::vector<std::string> vargs_;
1098  std::vector<char*> cargv_;
1099 
1100  bool child_created_ = false;
1101  // Pid of the child process
1102  int child_pid_ = -1;
1103 
1104  int retcode_ = -1;
1105 };
1106 
1107 inline void Popen::init_args() {
1108  populate_c_argv();
1109 }
1110 
1111 template <typename F, typename... Args>
1112 inline void Popen::init_args(F&& farg, Args&&... args)
1113 {
1114  detail::ArgumentDeducer argd(this);
1115  argd.set_option(std::forward<F>(farg));
1116  init_args(std::forward<Args>(args)...);
1117 }
1118 
1120 {
1121  cargv_.clear();
1122  cargv_.reserve(vargs_.size() + 1);
1123  for (auto& arg : vargs_) cargv_.push_back(&arg[0]);
1124  cargv_.push_back(nullptr);
1125 }
1126 
1127 inline int Popen::wait() noexcept(false)
1128 {
1129 #ifdef __USING_WINDOWS__
1130  int ret = WaitForSingleObject(process_handle_, INFINITE);
1131 
1132  return 0;
1133 #else
1134  int ret, status;
1135  std::tie(ret, status) = util::wait_for_child_exit(pid());
1136  if (ret == -1) {
1137  if (errno != ECHILD) throw OSError("waitpid failed", errno);
1138  return 0;
1139  }
1140  if (WIFEXITED(status)) return WEXITSTATUS(status);
1141  if (WIFSIGNALED(status)) return WTERMSIG(status);
1142  else return 255;
1143 
1144  return 0;
1145 #endif
1146 }
1147 
1148 inline int Popen::poll() noexcept(false)
1149 {
1150 #ifdef __USING_WINDOWS__
1151  int ret = WaitForSingleObject(process_handle_, 0);
1152  if (ret != WAIT_OBJECT_0) return -1;
1153 
1154  DWORD dretcode_;
1155  if (FALSE == GetExitCodeProcess(process_handle_, &dretcode_))
1156  throw OSError("GetExitCodeProcess", 0);
1157 
1158  retcode_ = (int)dretcode_;
1159  CloseHandle(process_handle_);
1160 
1161  return retcode_;
1162 #else
1163  if (!child_created_) return -1; // TODO: ??
1164 
1165  int status;
1166 
1167  // Returns zero if child is still running
1168  int ret = waitpid(child_pid_, &status, WNOHANG);
1169  if (ret == 0) return -1;
1170 
1171  if (ret == child_pid_) {
1172  if (WIFSIGNALED(status)) {
1173  retcode_ = WTERMSIG(status);
1174  } else if (WIFEXITED(status)) {
1175  retcode_ = WEXITSTATUS(status);
1176  } else {
1177  retcode_ = 255;
1178  }
1179  return retcode_;
1180  }
1181 
1182  if (ret == -1) {
1183  // From subprocess.py
1184  // This happens if SIGCHLD is set to be ignored
1185  // or waiting for child process has otherwise been disabled
1186  // for our process. This child is dead, we cannot get the
1187  // status.
1188  if (errno == ECHILD) retcode_ = 0;
1189  else throw OSError("waitpid failed", errno);
1190  } else {
1191  retcode_ = ret;
1192  }
1193 
1194  return retcode_;
1195 #endif
1196 }
1197 
1198 inline void Popen::kill(int sig_num)
1199 {
1200 #ifdef __USING_WINDOWS__
1201  if (!TerminateProcess(this->process_handle_, (UINT)sig_num)) {
1202  throw OSError("TerminateProcess", 0);
1203  }
1204 #else
1205  ::kill(child_pid_, sig_num);
1206 #endif
1207 }
1208 
1209 
1210 inline void Popen::execute_process() noexcept(false)
1211 {
1212 #ifdef __USING_WINDOWS__
1213  if (exe_name_.length()) {
1214  this->vargs_.insert(this->vargs_.begin(), this->exe_name_);
1215  this->populate_c_argv();
1216  }
1217  this->exe_name_ = vargs_[0];
1218 
1219  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
1220  std::wstring argument;
1221  std::wstring command_line;
1222 
1223  for (auto arg : this->vargs_) {
1224  argument = converter.from_bytes(arg);
1225  util::quote_argument(argument, command_line, false);
1226  command_line += L" ";
1227  }
1228 
1229  // CreateProcessW can modify szCmdLine so we allocate needed memory
1230  wchar_t *szCmdline = new wchar_t[command_line.size() + 1];
1231  wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
1232  PROCESS_INFORMATION piProcInfo;
1233  STARTUPINFOW siStartInfo;
1234  BOOL bSuccess = FALSE;
1235  DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
1236 
1237  // Set up members of the PROCESS_INFORMATION structure.
1238  ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
1239 
1240  // Set up members of the STARTUPINFOW structure.
1241  // This structure specifies the STDIN and STDOUT handles for redirection.
1242 
1243  ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW));
1244  siStartInfo.cb = sizeof(STARTUPINFOW);
1245 
1246  siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
1247  siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
1248  siStartInfo.hStdInput = this->stream_.g_hChildStd_IN_Rd;
1249 
1250  siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
1251 
1252  // Create the child process.
1253  bSuccess = CreateProcessW(NULL,
1254  szCmdline, // command line
1255  NULL, // process security attributes
1256  NULL, // primary thread security attributes
1257  TRUE, // handles are inherited
1258  creation_flags, // creation flags
1259  NULL, // use parent's environment
1260  NULL, // use parent's current directory
1261  &siStartInfo, // STARTUPINFOW pointer
1262  &piProcInfo); // receives PROCESS_INFORMATION
1263 
1264  // If an error occurs, exit the application.
1265  if (!bSuccess) {
1266  DWORD errorMessageID = ::GetLastError();
1267  throw CalledProcessError("CreateProcess failed: " + util::get_last_error(errorMessageID), errorMessageID);
1268  }
1269 
1270  CloseHandle(piProcInfo.hThread);
1271 
1272  /*
1273  TODO: use common apis to close linux handles
1274  */
1275 
1276  this->process_handle_ = piProcInfo.hProcess;
1277 
1278  this->cleanup_future_ = std::async(std::launch::async, [this] {
1279  WaitForSingleObject(this->process_handle_, INFINITE);
1280 
1281  CloseHandle(this->stream_.g_hChildStd_ERR_Wr);
1282  CloseHandle(this->stream_.g_hChildStd_OUT_Wr);
1283  CloseHandle(this->stream_.g_hChildStd_IN_Rd);
1284  });
1285 
1286 /*
1287  NOTE: In the linux version, there is a check to make sure that the process
1288  has been started. Here, we do nothing because CreateProcess will throw
1289  if we fail to create the process.
1290 */
1291 
1292 
1293 #else
1294 
1295  int err_rd_pipe, err_wr_pipe;
1296  std::tie(err_rd_pipe, err_wr_pipe) = util::pipe_cloexec();
1297 
1298  if (exe_name_.length()) {
1299  vargs_.insert(vargs_.begin(), exe_name_);
1300  populate_c_argv();
1301  }
1302  exe_name_ = vargs_[0];
1303 
1304  child_pid_ = fork();
1305 
1306  if (child_pid_ < 0) {
1307  close(err_rd_pipe);
1308  close(err_wr_pipe);
1309  throw OSError("fork failed", errno);
1310  }
1311 
1312  child_created_ = true;
1313 
1314  if (child_pid_ == 0)
1315  {
1316  // Close descriptors belonging to parent
1318 
1319  //Close the read end of the error pipe
1320  close(err_rd_pipe);
1321 
1322  detail::Child chld(this, err_wr_pipe);
1323  chld.execute_child();
1324  }
1325  else
1326  {
1327  close (err_wr_pipe);// close child side of pipe, else get stuck in read below
1328 
1330 
1331  try {
1332  char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1333 
1334  int read_bytes = util::read_atmost_n(
1335  fdopen(err_rd_pipe, "r"),
1336  err_buf,
1338  close(err_rd_pipe);
1339 
1340  if (read_bytes || strlen(err_buf)) {
1341  // Call waitpid to reap the child process
1342  // waitpid suspends the calling process until the
1343  // child terminates.
1344  int retcode = wait();
1345 
1346  // Throw whatever information we have about child failure
1347  throw CalledProcessError(err_buf, retcode);
1348  }
1349  } catch (std::exception& exp) {
1350  stream_.cleanup_fds();
1351  throw;
1352  }
1353 
1354  }
1355 #endif
1356 }
1357 
1358 namespace detail {
1359 
1361  popen_->exe_name_ = std::move(exe.arg_value);
1362  }
1363 
1364  inline void ArgumentDeducer::set_option(input&& inp) {
1365  if (inp.rd_ch_ != -1) popen_->stream_.read_from_parent_ = inp.rd_ch_;
1366  if (inp.wr_ch_ != -1) popen_->stream_.write_to_child_ = inp.wr_ch_;
1367  }
1368 
1370  if (out.wr_ch_ != -1) popen_->stream_.write_to_parent_ = out.wr_ch_;
1371  if (out.rd_ch_ != -1) popen_->stream_.read_from_child_ = out.rd_ch_;
1372  }
1373 
1374  inline void ArgumentDeducer::set_option(error&& err) {
1375  if (err.deferred_) {
1378  } else {
1379  throw std::runtime_error("Set output before redirecting error to output");
1380  }
1381  }
1382  if (err.wr_ch_ != -1) popen_->stream_.err_write_ = err.wr_ch_;
1383  if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1384  }
1385 
1386 
1387  inline void Child::execute_child() {
1388 #ifndef __USING_WINDOWS__
1389  int sys_ret = -1;
1390  auto& stream = parent_->stream_;
1391 
1392  try {
1393  if (stream.write_to_parent_ == 0)
1394  stream.write_to_parent_ = dup(stream.write_to_parent_);
1395 
1396  if (stream.err_write_ == 0 || stream.err_write_ == 1)
1397  stream.err_write_ = dup(stream.err_write_);
1398 
1399  // Make the child owned descriptors as the
1400  // stdin, stdout and stderr for the child process
1401  auto _dup2_ = [](int fd, int to_fd) {
1402  if (fd == to_fd) {
1403  // dup2 syscall does not reset the
1404  // CLOEXEC flag if the descriptors
1405  // provided to it are same.
1406  // But, we need to reset the CLOEXEC
1407  // flag as the provided descriptors
1408  // are now going to be the standard
1409  // input, output and error
1410  util::set_clo_on_exec(fd, false);
1411  } else if(fd != -1) {
1412  int res = dup2(fd, to_fd);
1413  if (res == -1) throw OSError("dup2 failed", errno);
1414  }
1415  };
1416 
1417  // Create the standard streams
1418  _dup2_(stream.read_from_parent_, 0); // Input stream
1419  _dup2_(stream.write_to_parent_, 1); // Output stream
1420  _dup2_(stream.err_write_, 2); // Error stream
1421 
1422  // Close the duped descriptors
1423  if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1424  close(stream.read_from_parent_);
1425 
1426  if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1427  close(stream.write_to_parent_);
1428 
1429  if (stream.err_write_ != -1 && stream.err_write_ > 2)
1430  close(stream.err_write_);
1431 
1432  // Replace the current image with the executable
1433  sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1434 
1435  if (sys_ret == -1) throw OSError("execve failed", errno);
1436 
1437  } catch (const OSError& exp) {
1438  // Just write the exception message
1439  // TODO: Give back stack trace ?
1440  std::string err_msg(exp.what());
1441  //ATTN: Can we do something on error here ?
1442  util::write_n(err_wr_pipe_, err_msg.c_str(), err_msg.length());
1443  }
1444 
1445  // Calling application would not get this
1446  // exit failure
1447  _exit (EXIT_FAILURE);
1448 #endif
1449  }
1450 
1451 
1453  {
1454 #ifdef __USING_WINDOWS__
1455  util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1456  this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1457  this->write_to_child_ = _fileno(this->input());
1458 
1459  util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1460  this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1461  this->read_from_child_ = _fileno(this->output());
1462 
1463  util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1464  this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1465  this->err_read_ = _fileno(this->error());
1466 #else
1467 
1468  if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
1469  if (read_from_child_ != -1) output(fdopen(read_from_child_, "rb"));
1470  if (err_read_ != -1) error(fdopen(err_read_, "rb"));
1471 
1472  auto handles = {input(), output(), error()};
1473 
1474  for (auto& h : handles) {
1475  if (h == nullptr) continue;
1476  setvbuf(h, nullptr, _IONBF, BUFSIZ);
1477  }
1478  #endif
1479  }
1480 
1481  inline int Communication::send(const char* msg, size_t length)
1482  {
1483  if (stream_->input() == nullptr) return -1;
1484  return std::fwrite(msg, sizeof(char), length, stream_->input());
1485  }
1486 
1487  inline int Communication::send(const std::vector<char>& msg)
1488  {
1489  return send(msg.data(), msg.size());
1490  }
1491 
1492  inline std::pair<OutBuffer, ErrBuffer>
1493  Communication::communicate(const char* msg, size_t length)
1494  {
1495  // Optimization from subprocess.py
1496  // If we are using one pipe, or no pipe
1497  // at all, using select() or threads is unnecessary.
1498  auto hndls = {stream_->input(), stream_->output(), stream_->error()};
1499  int count = std::count(std::begin(hndls), std::end(hndls), nullptr);
1500  const int len_conv = length;
1501 
1502  if (count >= 2) {
1503  OutBuffer obuf;
1504  ErrBuffer ebuf;
1505  if (stream_->input()) {
1506  if (msg) {
1507  int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1508  if (wbytes < len_conv) {
1509  if (errno != EPIPE && errno != EINVAL) {
1510  throw OSError("fwrite error", errno);
1511  }
1512  }
1513  }
1514  // Close the input stream
1515  stream_->input_.reset();
1516  } else if (stream_->output()) {
1517  // Read till EOF
1518  // ATTN: This could be blocking, if the process
1519  // at the other end screws up, we get screwed as well
1520  obuf.add_cap(out_buf_cap_);
1521 
1522  int rbytes = util::read_all(
1523  stream_->output(),
1524  obuf.buf);
1525 
1526  if (rbytes == -1) {
1527  throw OSError("read to obuf failed", errno);
1528  }
1529 
1530  obuf.length = rbytes;
1531  // Close the output stream
1532  stream_->output_.reset();
1533 
1534  } else if (stream_->error()) {
1535  // Same screwness applies here as well
1536  ebuf.add_cap(err_buf_cap_);
1537 
1538  int rbytes = util::read_atmost_n(
1539  stream_->error(),
1540  ebuf.buf.data(),
1541  ebuf.buf.size());
1542 
1543  if (rbytes == -1) {
1544  throw OSError("read to ebuf failed", errno);
1545  }
1546 
1547  ebuf.length = rbytes;
1548  // Close the error stream
1549  stream_->error_.reset();
1550  }
1551  return std::make_pair(std::move(obuf), std::move(ebuf));
1552  }
1553 
1554  return communicate_threaded(msg, length);
1555  }
1556 
1557 
1558  inline std::pair<OutBuffer, ErrBuffer>
1559  Communication::communicate_threaded(const char* msg, size_t length)
1560  {
1561  OutBuffer obuf;
1562  ErrBuffer ebuf;
1563  std::future<int> out_fut, err_fut;
1564  const int length_conv = length;
1565 
1566  if (stream_->output()) {
1567  obuf.add_cap(out_buf_cap_);
1568 
1569  out_fut = std::async(std::launch::async,
1570  [&obuf, this] {
1571  return util::read_all(this->stream_->output(), obuf.buf);
1572  });
1573  }
1574  if (stream_->error()) {
1575  ebuf.add_cap(err_buf_cap_);
1576 
1577  err_fut = std::async(std::launch::async,
1578  [&ebuf, this] {
1579  return util::read_all(this->stream_->error(), ebuf.buf);
1580  });
1581  }
1582  if (stream_->input()) {
1583  if (msg) {
1584  int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1585  if (wbytes < length_conv) {
1586  if (errno != EPIPE && errno != EINVAL) {
1587  throw OSError("fwrite error", errno);
1588  }
1589  }
1590  }
1591  stream_->input_.reset();
1592  }
1593 
1594  if (out_fut.valid()) {
1595  int res = out_fut.get();
1596  if (res != -1) obuf.length = res;
1597  else obuf.length = 0;
1598  }
1599  if (err_fut.valid()) {
1600  int res = err_fut.get();
1601  if (res != -1) ebuf.length = res;
1602  else ebuf.length = 0;
1603  }
1604 
1605  return std::make_pair(std::move(obuf), std::move(ebuf));
1606  }
1607 
1608 } // end namespace detail
1609 
1610 }
1611 
1612 #endif // SUBPROCESS_HPP
int ret
int flags
Definition: bitcoin-tx.cpp:530
ArgsManager & args
Definition: bitcoind.cpp:268
Buffer(size_t cap)
Definition: subprocess.hpp:686
void add_cap(size_t cap)
Definition: subprocess.hpp:687
std::vector< char > buf
Definition: subprocess.hpp:706
CalledProcessError(const std::string &error_msg, int retcode)
Definition: subprocess.hpp:133
OSError(const std::string &err_msg, int err_code)
Definition: subprocess.hpp:152
detail::Streams stream_
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
void set_out_buf_cap(size_t cap)
Popen(std::initializer_list< const char * > cmd_args, Args &&...args)
Definition: subprocess.hpp:988
std::vector< char * > cargv_
Popen(std::vector< std::string > vargs_, Args &&... args)
std::pair< OutBuffer, ErrBuffer > communicate(const std::string &msg)
void close_input()
Stream close APIs.
void execute_process() noexcept(false)
std::vector< std::string > vargs_
std::string exe_name_
void kill(int sig_num=9)
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
int send(const std::vector< char > &msg)
std::pair< OutBuffer, ErrBuffer > communicate()
int pid() const noexcept
int send(const std::string &msg)
int retcode() const noexcept
Popen(const std::string &cmd_args, Args &&...args)
Definition: subprocess.hpp:975
int wait() noexcept(false)
void set_err_buf_cap(size_t cap)
int send(const char *msg, size_t length)
std::string args_
int poll() noexcept(false)
Child(Popen *p, int err_wr_pipe)
Definition: subprocess.hpp:783
void operator=(const Communication &)=delete
int send(const char *msg, size_t length)
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.hpp:817
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
std::pair< OutBuffer, ErrBuffer > communicate_threaded(const char *msg, size_t length)
int send(const std::vector< char > &msg)
Definition: subprocess.hpp:895
void set_out_buf_cap(size_t cap)
Definition: subprocess.hpp:888
void set_err_buf_cap(size_t cap)
Definition: subprocess.hpp:889
void operator=(const Streams &)=delete
std::shared_ptr< FILE > output_
Definition: subprocess.hpp:908
std::shared_ptr< FILE > error_
Definition: subprocess.hpp:909
int send(const char *msg, size_t length)
Definition: subprocess.hpp:892
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.hpp:901
std::shared_ptr< FILE > input_
Definition: subprocess.hpp:907
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.hpp:898
#define T(expected, seed, data)
static std::pair< int, int > wait_for_child_exit(int pid)
Definition: subprocess.hpp:503
static int read_all(FILE *fp, std::vector< char > &buf)
Definition: subprocess.hpp:454
void quote_argument(const std::wstring &argument, std::wstring &command_line, bool force)
Definition: subprocess.hpp:166
bool is_ready(std::shared_future< R > const &f)
Definition: subprocess.hpp:161
static std::pair< int, int > pipe_cloexec() noexcept(false)
Definition: subprocess.hpp:358
static int read_atmost_n(FILE *fp, char *buf, size_t read_upto)
Definition: subprocess.hpp:413
static void set_clo_on_exec(int fd, bool set=true)
Definition: subprocess.hpp:338
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.hpp:307
static int write_n(int fd, const char *buf, size_t length)
Definition: subprocess.hpp:386
static const size_t SP_MAX_ERR_BUF_SIZ
Definition: subprocess.hpp:109
static const size_t DEFAULT_BUF_CAP_BYTES
Definition: subprocess.hpp:114
void set_option(executable &&exe)
error(IOTYPE typ)
Definition: subprocess.hpp:651
error(const char *filename)
Definition: subprocess.hpp:646
input(const char *filename)
Definition: subprocess.hpp:582
input(IOTYPE typ)
Definition: subprocess.hpp:587
output(IOTYPE typ)
Definition: subprocess.hpp:620
output(const char *filename)
Definition: subprocess.hpp:615
string_arg(const char *arg)
Definition: subprocess.hpp:532
string_arg(std::string arg)
Definition: subprocess.hpp:534
string_arg(std::string &&arg)
Definition: subprocess.hpp:533
static int count
assert(!tx.IsCoinBase())