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