Bitcoin Core 31.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/check.h>
40#include <util/syserror.h>
41
42#include <algorithm>
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 <map>
52#include <memory>
53#include <sstream>
54#include <string>
55#include <vector>
56
57extern "C" {
58#ifdef WIN32
59 #include <windows.h>
60 #include <io.h>
61#else
62 #include <sys/wait.h>
63 #include <unistd.h>
64#endif
65 #include <csignal>
66 #include <fcntl.h>
67 #include <sys/types.h>
68}
69
70// The Microsoft C++ compiler issues deprecation warnings
71// for the standard POSIX function names.
72// Its preferred implementations have a leading underscore.
73// See: https://learn.microsoft.com/en-us/cpp/c-runtime-library/compatibility.
74#if (defined _MSC_VER)
75 #define subprocess_close _close
76 #define subprocess_fileno _fileno
77 #define subprocess_open _open
78 #define subprocess_write _write
79#else
80 #define subprocess_close close
81 #define subprocess_fileno fileno
82 #define subprocess_open open
83 #define subprocess_write write
84#endif
85
109namespace subprocess {
110
111// Max buffer size allocated on stack for read error
112// from pipe
113static const size_t SP_MAX_ERR_BUF_SIZ = 1024;
114
115// Default buffer capacity for OutBuffer and ErrBuffer.
116// If the data exceeds this capacity, the buffer size is grown
117// by 1.5 times its previous capacity
118static const size_t DEFAULT_BUF_CAP_BYTES = 8192;
119
120
121/*-----------------------------------------------
122 * EXCEPTION CLASSES
123 *-----------------------------------------------
124 */
125
133class CalledProcessError: public std::runtime_error
134{
135public:
137 CalledProcessError(const std::string& error_msg, int retcode):
138 std::runtime_error(error_msg), retcode(retcode)
139 {}
140};
141
142
153class OSError: public std::runtime_error
154{
155public:
156 OSError(const std::string& err_msg, int err_code):
157 std::runtime_error(err_msg + ": " + SysErrorString(err_code))
158 {}
159};
160
161//--------------------------------------------------------------------
162namespace util
163{
164#ifdef WIN32
165 inline void quote_argument(const std::string &argument, std::string &command_line,
166 bool force)
167 {
168 constexpr char quote = '"';
169 constexpr char backslash = '\\';
170
171 //
172 // Unless we're told otherwise, don't quote unless we actually
173 // need to do so --- hopefully avoid problems if programs won't
174 // parse quotes properly
175 //
176
177 if (force == false && argument.empty() == false &&
178 argument.find_first_of(" \t\n\v") == argument.npos) {
179 command_line.append(argument);
180 }
181 else {
182 command_line.push_back(quote);
183
184 for (auto it = argument.begin();; ++it) {
185 unsigned number_backslashes = 0;
186
187 while (it != argument.end() && *it == backslash) {
188 ++it;
189 ++number_backslashes;
190 }
191
192 if (it == argument.end()) {
193
194 //
195 // Escape all backslashes, but let the terminating
196 // double quotation mark we add below be interpreted
197 // as a metacharacter.
198 //
199
200 command_line.append(number_backslashes * 2, backslash);
201 break;
202 }
203 else if (*it == quote) {
204
205 //
206 // Escape all backslashes and the following
207 // double quotation mark.
208 //
209
210 command_line.append(number_backslashes * 2 + 1, backslash);
211 command_line.push_back(*it);
212 }
213 else {
214
215 //
216 // Backslashes aren't special here.
217 //
218
219 command_line.append(number_backslashes, backslash);
220 command_line.push_back(*it);
221 }
222 }
223
224 command_line.push_back(quote);
225 }
226 }
227
228 inline std::string get_last_error(DWORD errorMessageID)
229 {
230 if (errorMessageID == 0)
231 return std::string();
232
233 LPSTR messageBuffer = nullptr;
234 size_t size = FormatMessageA(
235 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
236 FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
237 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
238 (LPSTR)&messageBuffer, 0, NULL);
239
240 std::string message(messageBuffer, size);
241
242 LocalFree(messageBuffer);
243
244 return message;
245 }
246
247 inline FILE *file_from_handle(HANDLE h, const char *mode)
248 {
249 int md;
250 if (!mode) {
251 throw OSError("invalid_mode", 0);
252 }
253
254 if (mode[0] == 'w') {
255 md = _O_WRONLY;
256 }
257 else if (mode[0] == 'r') {
258 md = _O_RDONLY;
259 }
260 else {
261 throw OSError("file_from_handle", 0);
262 }
263
264 int os_fhandle = _open_osfhandle((intptr_t)h, md);
265 if (os_fhandle == -1) {
266 CloseHandle(h);
267 throw OSError("_open_osfhandle", 0);
268 }
269
270 FILE *fp = _fdopen(os_fhandle, mode);
271 if (fp == 0) {
272 subprocess_close(os_fhandle);
273 throw OSError("_fdopen", 0);
274 }
275
276 return fp;
277 }
278
279 inline void configure_pipe(HANDLE* read_handle, HANDLE* write_handle, HANDLE* child_handle)
280 {
281 SECURITY_ATTRIBUTES saAttr;
282
283 // Set the bInheritHandle flag so pipe handles are inherited.
284 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
285 saAttr.bInheritHandle = TRUE;
286 saAttr.lpSecurityDescriptor = NULL;
287
288 // Create a pipe for the child process's STDIN.
289 if (!CreatePipe(read_handle, write_handle, &saAttr,0))
290 throw OSError("CreatePipe", 0);
291
292 // Ensure the write handle to the pipe for STDIN is not inherited.
293 if (!SetHandleInformation(*child_handle, HANDLE_FLAG_INHERIT, 0))
294 throw OSError("SetHandleInformation", 0);
295 }
296#endif
297
307 static inline std::vector<std::string>
308 split(const std::string& str, const std::string& delims=" \t")
309 {
310 std::vector<std::string> res;
311 size_t init = 0;
312
313 while (true) {
314 auto pos = str.find_first_of(delims, init);
315 if (pos == std::string::npos) {
316 res.emplace_back(str.substr(init, str.length()));
317 break;
318 }
319 res.emplace_back(str.substr(init, pos - init));
320 pos++;
321 init = pos;
322 }
323
324 return res;
325 }
326
327
328#ifndef WIN32
338 static inline
339 void set_clo_on_exec(int fd, bool set = true)
340 {
341 int flags = fcntl(fd, F_GETFD, 0);
342 if (flags == -1) {
343 throw OSError("fcntl F_GETFD failed", errno);
344 }
345 if (set) flags |= FD_CLOEXEC;
346 else flags &= ~FD_CLOEXEC;
347 if (fcntl(fd, F_SETFD, flags) == -1) {
348 throw OSError("fcntl F_SETFD failed", errno);
349 }
350 }
351
352
362 static inline
363 std::pair<int, int> pipe_cloexec() noexcept(false)
364 {
365 int pipe_fds[2];
366 int res = pipe(pipe_fds);
367 if (res) {
368 throw OSError("pipe failure", errno);
369 }
370
371 set_clo_on_exec(pipe_fds[0]);
372 set_clo_on_exec(pipe_fds[1]);
373
374 return std::make_pair(pipe_fds[0], pipe_fds[1]);
375 }
376#endif
377
378
390 static inline
391 int write_n(int fd, const char* buf, size_t length)
392 {
393 size_t nwritten = 0;
394 while (nwritten < length) {
395 int written = subprocess_write(fd, buf + nwritten, length - nwritten);
396 if (written == -1) return -1;
397 nwritten += written;
398 }
399 return nwritten;
400 }
401
402
417 static inline
418 int read_atmost_n(FILE* fp, char* buf, size_t read_upto)
419 {
420#ifdef WIN32
421 return (int)fread(buf, 1, read_upto, fp);
422#else
423 int fd = subprocess_fileno(fp);
424 int rbytes = 0;
425 int eintr_cnter = 0;
426
427 while (1) {
428 int read_bytes = read(fd, buf + rbytes, read_upto - rbytes);
429 if (read_bytes == -1) {
430 if (errno == EINTR) {
431 if (eintr_cnter >= 50) return -1;
432 eintr_cnter++;
433 continue;
434 }
435 return -1;
436 }
437 if (read_bytes == 0) return rbytes;
438
439 rbytes += read_bytes;
440 }
441 return rbytes;
442#endif
443 }
444
445
459 static inline int read_all(FILE* fp, std::vector<char>& buf)
460 {
461 auto buffer = buf.data();
462 int total_bytes_read = 0;
463 int fill_sz = buf.size();
464
465 while (1) {
466 const int rd_bytes = read_atmost_n(fp, buffer, fill_sz);
467
468 if (rd_bytes == -1) { // Read finished
469 if (total_bytes_read == 0) return -1;
470 break;
471
472 } else if (rd_bytes == fill_sz) { // Buffer full
473 const auto orig_sz = buf.size();
474 const auto new_sz = orig_sz * 2;
475 buf.resize(new_sz);
476 fill_sz = new_sz - orig_sz;
477
478 //update the buffer pointer
479 buffer = buf.data();
480 total_bytes_read += rd_bytes;
481 buffer += total_bytes_read;
482
483 } else { // Partial data ? Continue reading
484 total_bytes_read += rd_bytes;
485 fill_sz -= rd_bytes;
486 break;
487 }
488 }
489 buf.erase(buf.begin()+total_bytes_read, buf.end()); // remove extra nulls
490 return total_bytes_read;
491 }
492
493#ifndef WIN32
507 static inline
508 std::pair<int, int> wait_for_child_exit(int pid)
509 {
510 int status = 0;
511 int ret = -1;
512 while (1) {
513 ret = waitpid(pid, &status, 0);
514 if (ret == -1) break;
515 if (ret == 0) continue;
516 return std::make_pair(ret, status);
517 }
518
519 return std::make_pair(ret, status);
520 }
521#endif
522
523} // end namespace util
524
525
526
527/* -------------------------------
528 * Popen Arguments
529 * -------------------------------
530 */
531
536{
537 string_arg(const char* arg): arg_value(arg) {}
538 string_arg(std::string&& arg): arg_value(std::move(arg)) {}
539 string_arg(const std::string& arg): arg_value(arg) {}
540 std::string arg_value;
541};
542
552{
553 template <typename T>
554 executable(T&& arg): string_arg(std::forward<T>(arg)) {}
555};
556
560enum IOTYPE {
564};
565
566//TODO: A common base/interface for below stream structures ??
567
579struct input
580{
581 // For an already existing file descriptor.
582 explicit input(int fd): rd_ch_(fd) {}
583
584 // FILE pointer.
585 explicit input (FILE* fp):input(subprocess_fileno(fp)) { assert(fp); }
586
587 explicit input(const char* filename) {
588 int fd = subprocess_open(filename, O_RDONLY);
589 if (fd == -1) throw OSError("File not found: ", errno);
590 rd_ch_ = fd;
591 }
592 explicit input(IOTYPE typ) {
593 assert (typ == PIPE && "STDOUT/STDERR not allowed");
594#ifndef WIN32
595 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
596#endif
597 }
598
599 int rd_ch_ = -1;
600 int wr_ch_ = -1;
601};
602
603
614struct output
615{
616 explicit output(int fd): wr_ch_(fd) {}
617
618 explicit output (FILE* fp):output(subprocess_fileno(fp)) { assert(fp); }
619
620 explicit output(const char* filename) {
621 int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
622 if (fd == -1) throw OSError("File not found: ", errno);
623 wr_ch_ = fd;
624 }
625 explicit output(IOTYPE typ) {
626 assert (typ == PIPE && "STDOUT/STDERR not allowed");
627#ifndef WIN32
628 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
629#endif
630 }
631
632 int rd_ch_ = -1;
633 int wr_ch_ = -1;
634};
635
636
645struct error
646{
647 explicit error(int fd): wr_ch_(fd) {}
648
649 explicit error(FILE* fp):error(subprocess_fileno(fp)) { assert(fp); }
650
651 explicit error(const char* filename) {
652 int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
653 if (fd == -1) throw OSError("File not found: ", errno);
654 wr_ch_ = fd;
655 }
656 explicit error(IOTYPE typ) {
657 assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed");
658 if (typ == PIPE) {
659#ifndef WIN32
660 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
661#endif
662 } else {
663 // Need to defer it till we have checked all arguments
664 deferred_ = true;
665 }
666 }
667
668 bool deferred_ = false;
669 int rd_ch_ = -1;
670 int wr_ch_ = -1;
671};
672
673// ~~~~ End Popen Args ~~~~
674
675
688{
689public:
690 Buffer() = default;
691 explicit Buffer(size_t cap) { buf.resize(cap); }
692 void add_cap(size_t cap) { buf.resize(cap); }
693
694public:
695 std::vector<char> buf;
696 size_t length = 0;
697};
698
699// Buffer for storing output written to output fd
701// Buffer for storing output written to error fd
703
704
705// Fwd Decl.
706class Popen;
707
708/*---------------------------------------------------
709 * DETAIL NAMESPACE
710 *---------------------------------------------------
711 */
712
713namespace detail {
722{
724
725 void set_option(executable&& exe);
726 void set_option(input&& inp);
727 void set_option(output&& out);
728 void set_option(error&& err);
729
730private:
731 Popen* popen_ = nullptr;
732};
733
734#ifndef WIN32
740class Child
741{
742public:
743 Child(Popen* p, int err_wr_pipe):
744 parent_(p),
745 err_wr_pipe_(err_wr_pipe)
746 {}
747
748 void execute_child();
749
750private:
751 // Lets call it parent even though
752 // technically a bit incorrect
753 Popen* parent_ = nullptr;
754 int err_wr_pipe_ = -1;
755};
756#endif
757
758// Fwd Decl.
759class Streams;
760
768{
769public:
770 Communication(Streams* stream): stream_(stream)
771 {}
772 Communication(const Communication&) = delete;
776public:
777 int send(const char* msg, size_t length);
778 int send(const std::vector<char>& msg);
779
780 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length);
781 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
782 { return communicate(msg.data(), msg.size()); }
783
784 void set_out_buf_cap(size_t cap) { out_buf_cap_ = cap; }
785 void set_err_buf_cap(size_t cap) { err_buf_cap_ = cap; }
786
787private:
788 std::pair<OutBuffer, ErrBuffer> communicate_threaded(
789 const char* msg, size_t length);
790
791private:
795};
796
797
798
809{
810public:
811 Streams():comm_(this) {}
812 Streams(const Streams&) = delete;
813 Streams& operator=(const Streams&) = delete;
814 Streams(Streams&&) = default;
815 Streams& operator=(Streams&&) = default;
816
817public:
818 void setup_comm_channels();
819
821 {
822 if (write_to_child_ != -1 && read_from_parent_ != -1) {
824 }
825 if (write_to_parent_ != -1 && read_from_child_ != -1) {
827 }
828 if (err_write_ != -1 && err_read_ != -1) {
830 }
831 }
832
834 {
838 }
839
841 {
845 }
846
847 FILE* input() { return input_.get(); }
848 FILE* output() { return output_.get(); }
849 FILE* error() { return error_.get(); }
850
851 void input(FILE* fp) { input_.reset(fp, fclose); }
852 void output(FILE* fp) { output_.reset(fp, fclose); }
853 void error(FILE* fp) { error_.reset(fp, fclose); }
854
855 void set_out_buf_cap(size_t cap) { comm_.set_out_buf_cap(cap); }
856 void set_err_buf_cap(size_t cap) { comm_.set_err_buf_cap(cap); }
857
858public: /* Communication forwarding API's */
859 int send(const char* msg, size_t length)
860 { return comm_.send(msg, length); }
861
862 int send(const std::vector<char>& msg)
863 { return comm_.send(msg); }
864
865 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
866 { return comm_.communicate(msg, length); }
867
868 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
869 { return comm_.communicate(msg); }
870
871
872public:// Yes they are public
873
874 std::shared_ptr<FILE> input_ = nullptr;
875 std::shared_ptr<FILE> output_ = nullptr;
876 std::shared_ptr<FILE> error_ = nullptr;
877
878#ifdef WIN32
879 HANDLE g_hChildStd_IN_Rd = nullptr;
880 HANDLE g_hChildStd_IN_Wr = nullptr;
881 HANDLE g_hChildStd_OUT_Rd = nullptr;
882 HANDLE g_hChildStd_OUT_Wr = nullptr;
883 HANDLE g_hChildStd_ERR_Rd = nullptr;
884 HANDLE g_hChildStd_ERR_Wr = nullptr;
885#endif
886
887 // Pipes for communicating with child
888
889 // Emulates stdin
890 int write_to_child_ = -1; // Parent owned descriptor
891 int read_from_parent_ = -1; // Child owned descriptor
892
893 // Emulates stdout
894 int write_to_parent_ = -1; // Child owned descriptor
895 int read_from_child_ = -1; // Parent owned descriptor
896
897 // Emulates stderr
898 int err_write_ = -1; // Write error to parent (Child owned)
899 int err_read_ = -1; // Read error from child (Parent owned)
900
901private:
903};
904
905} // end namespace detail
906
907
908
924class Popen
925{
926public:
928#ifndef WIN32
929 friend class detail::Child;
930#endif
931
932 template <typename... Args>
933 Popen(std::initializer_list<const char*> cmd_args, Args&& ...args)
934 {
935 vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end());
936 init_args(std::forward<Args>(args)...);
937
938 // Setup the communication channels of the Popen class
940
942 }
943
944 template <typename... Args>
945 Popen(std::vector<std::string> vargs_, Args &&... args) : vargs_(vargs_)
946 {
947 init_args(std::forward<Args>(args)...);
948
949 // Setup the communication channels of the Popen class
951
953 }
954
955 int retcode() const noexcept { return retcode_; }
956
957 int wait() noexcept(false);
958
959 void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); }
960
961 void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); }
962
963 int send(const char* msg, size_t length)
964 { return stream_.send(msg, length); }
965
966 int send(const std::string& msg)
967 { return send(msg.c_str(), msg.size()); }
968
969 int send(const std::vector<char>& msg)
970 { return stream_.send(msg); }
971
972 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
973 {
974 auto res = stream_.communicate(msg, length);
975 retcode_ = wait();
976 return res;
977 }
978
979 std::pair<OutBuffer, ErrBuffer> communicate(const std::string& msg)
980 {
981 return communicate(msg.c_str(), msg.size());
982 }
983
984 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
985 {
986 auto res = stream_.communicate(msg);
987 retcode_ = wait();
988 return res;
989 }
990
991 std::pair<OutBuffer, ErrBuffer> communicate()
992 {
993 return communicate(nullptr, 0);
994 }
995
996private:
997 template <typename F, typename... Args>
998 void init_args(F&& farg, Args&&... args);
999 void init_args();
1000 void populate_c_argv();
1001 void execute_process() noexcept(false);
1002
1003private:
1004 detail::Streams stream_;
1005
1006#ifdef WIN32
1007 HANDLE process_handle_;
1008 std::future<void> cleanup_future_;
1009#else
1010 // Pid of the child process
1011 int child_pid_ = -1;
1012#endif
1013
1014 std::string exe_name_;
1015
1016 // Command provided as sequence
1017 std::vector<std::string> vargs_;
1018 std::vector<char*> cargv_;
1019
1020 int retcode_ = -1;
1021};
1022
1023inline void Popen::init_args() {
1025}
1026
1027template <typename F, typename... Args>
1028inline void Popen::init_args(F&& farg, Args&&... args)
1029{
1030 detail::ArgumentDeducer argd(this);
1031 argd.set_option(std::forward<F>(farg));
1032 init_args(std::forward<Args>(args)...);
1033}
1034
1036{
1037 cargv_.clear();
1038 cargv_.reserve(vargs_.size() + 1);
1039 for (auto& arg : vargs_) cargv_.push_back(&arg[0]);
1040 cargv_.push_back(nullptr);
1041}
1042
1043inline int Popen::wait() noexcept(false)
1044{
1045#ifdef WIN32
1046 int ret = WaitForSingleObject(process_handle_, INFINITE);
1047
1048 // WaitForSingleObject with INFINITE should only return when process has signaled
1049 if (ret != WAIT_OBJECT_0) {
1050 throw OSError("Unexpected return code from WaitForSingleObject", 0);
1051 }
1052
1053 DWORD dretcode_;
1054
1055 if (FALSE == GetExitCodeProcess(process_handle_, &dretcode_))
1056 throw OSError("Failed during call to GetExitCodeProcess", 0);
1057
1058 CloseHandle(process_handle_);
1059
1060 return (int)dretcode_;
1061#else
1062 int ret, status;
1063 std::tie(ret, status) = util::wait_for_child_exit(child_pid_);
1064 if (ret == -1) {
1065 if (errno != ECHILD) throw OSError("waitpid failed", errno);
1066 return 0;
1067 }
1068 if (WIFEXITED(status)) return WEXITSTATUS(status);
1069 if (WIFSIGNALED(status)) return WTERMSIG(status);
1070 else return 255;
1071
1072 return 0;
1073#endif
1074}
1075
1076inline void Popen::execute_process() noexcept(false)
1077{
1078#ifdef WIN32
1079 if (exe_name_.length()) {
1080 this->vargs_.insert(this->vargs_.begin(), this->exe_name_);
1081 this->populate_c_argv();
1082 }
1083 this->exe_name_ = vargs_[0];
1084
1085 std::string argument;
1086 std::string command_line;
1087 bool first_arg = true;
1088
1089 for (auto arg : this->vargs_) {
1090 if (!first_arg) {
1091 command_line += " ";
1092 } else {
1093 first_arg = false;
1094 }
1095 argument = arg;
1096 util::quote_argument(argument, command_line, /*force=*/false);
1097 }
1098
1099 // CreateProcessA can modify szCmdLine so we allocate needed memory
1100 char *szCmdline = new char[command_line.size() + 1];
1101 strcpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
1102 PROCESS_INFORMATION piProcInfo;
1103 STARTUPINFOA siStartInfo;
1104 BOOL bSuccess = FALSE;
1105 DWORD creation_flags = CREATE_NO_WINDOW;
1106
1107 // Set up members of the PROCESS_INFORMATION structure.
1108 ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
1109
1110 // Set up members of the STARTUPINFOA structure.
1111 // This structure specifies the STDIN and STDOUT handles for redirection.
1112
1113 ZeroMemory(&siStartInfo, sizeof(STARTUPINFOA));
1114 siStartInfo.cb = sizeof(STARTUPINFOA);
1115
1116 siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
1117 siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
1118 siStartInfo.hStdInput = this->stream_.g_hChildStd_IN_Rd;
1119
1120 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
1121
1122 // Create the child process.
1123 bSuccess = CreateProcessA(NULL,
1124 szCmdline, // command line
1125 NULL, // process security attributes
1126 NULL, // primary thread security attributes
1127 TRUE, // handles are inherited
1128 creation_flags, // creation flags
1129 NULL, // use parent's environment
1130 NULL, // use parent's current directory
1131 &siStartInfo, // STARTUPINFOA pointer
1132 &piProcInfo); // receives PROCESS_INFORMATION
1133
1134 // If an error occurs, exit the application.
1135 if (!bSuccess) {
1136 DWORD errorMessageID = ::GetLastError();
1137 throw CalledProcessError("CreateProcess failed: " + util::get_last_error(errorMessageID), errorMessageID);
1138 }
1139
1140 CloseHandle(piProcInfo.hThread);
1141
1142 /*
1143 TODO: use common apis to close linux handles
1144 */
1145
1146 this->process_handle_ = piProcInfo.hProcess;
1147
1148 this->cleanup_future_ = std::async(std::launch::async, [this] {
1149 WaitForSingleObject(this->process_handle_, INFINITE);
1150
1151 CloseHandle(this->stream_.g_hChildStd_ERR_Wr);
1152 CloseHandle(this->stream_.g_hChildStd_OUT_Wr);
1153 CloseHandle(this->stream_.g_hChildStd_IN_Rd);
1154 });
1155
1156/*
1157 NOTE: In the linux version, there is a check to make sure that the process
1158 has been started. Here, we do nothing because CreateProcess will throw
1159 if we fail to create the process.
1160*/
1161
1162
1163#else
1164
1165 int err_rd_pipe, err_wr_pipe;
1166 std::tie(err_rd_pipe, err_wr_pipe) = util::pipe_cloexec();
1167
1168 if (exe_name_.length()) {
1169 vargs_.insert(vargs_.begin(), exe_name_);
1171 }
1172 exe_name_ = vargs_[0];
1173
1174 child_pid_ = fork();
1175
1176 if (child_pid_ < 0) {
1177 subprocess_close(err_rd_pipe);
1178 subprocess_close(err_wr_pipe);
1179 throw OSError("fork failed", errno);
1180 }
1181
1182 if (child_pid_ == 0)
1183 {
1184 // Close descriptors belonging to parent
1186
1187 //Close the read end of the error pipe
1188 subprocess_close(err_rd_pipe);
1189
1190 detail::Child chld(this, err_wr_pipe);
1191 chld.execute_child();
1192 }
1193 else
1194 {
1195 subprocess_close(err_wr_pipe);// close child side of pipe, else get stuck in read below
1196
1198
1199 try {
1200 char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1201
1202 FILE* err_fp = fdopen(err_rd_pipe, "r");
1203 if (!err_fp) {
1204 subprocess_close(err_rd_pipe);
1205 throw OSError("fdopen failed", errno);
1206 }
1207 int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
1208 fclose(err_fp);
1209
1210 if (read_bytes || strlen(err_buf)) {
1211 // Call waitpid to reap the child process
1212 // waitpid suspends the calling process until the
1213 // child terminates.
1214 int retcode = wait();
1215
1216 // Throw whatever information we have about child failure
1217 throw CalledProcessError(err_buf, retcode);
1218 }
1219 } catch (std::exception& exp) {
1221 throw;
1222 }
1223
1224 }
1225#endif
1226}
1227
1228namespace detail {
1229
1231 popen_->exe_name_ = std::move(exe.arg_value);
1232 }
1233
1235 if (inp.rd_ch_ != -1) popen_->stream_.read_from_parent_ = inp.rd_ch_;
1236 if (inp.wr_ch_ != -1) popen_->stream_.write_to_child_ = inp.wr_ch_;
1237 }
1238
1240 if (out.wr_ch_ != -1) popen_->stream_.write_to_parent_ = out.wr_ch_;
1241 if (out.rd_ch_ != -1) popen_->stream_.read_from_child_ = out.rd_ch_;
1242 }
1243
1245 if (err.deferred_) {
1248 } else {
1249 throw std::runtime_error("Set output before redirecting error to output");
1250 }
1251 }
1252 if (err.wr_ch_ != -1) popen_->stream_.err_write_ = err.wr_ch_;
1253 if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1254 }
1255
1256
1257#ifndef WIN32
1258 inline void Child::execute_child() {
1259 int sys_ret = -1;
1260 auto& stream = parent_->stream_;
1261
1262 try {
1263 if (stream.write_to_parent_ == 0)
1264 stream.write_to_parent_ = dup(stream.write_to_parent_);
1265
1266 if (stream.err_write_ == 0 || stream.err_write_ == 1)
1267 stream.err_write_ = dup(stream.err_write_);
1268
1269 // Make the child owned descriptors as the
1270 // stdin, stdout and stderr for the child process
1271 auto _dup2_ = [](int fd, int to_fd) {
1272 if (fd == to_fd) {
1273 // dup2 syscall does not reset the
1274 // CLOEXEC flag if the descriptors
1275 // provided to it are same.
1276 // But, we need to reset the CLOEXEC
1277 // flag as the provided descriptors
1278 // are now going to be the standard
1279 // input, output and error
1280 util::set_clo_on_exec(fd, false);
1281 } else if(fd != -1) {
1282 int res = dup2(fd, to_fd);
1283 if (res == -1) throw OSError("dup2 failed", errno);
1284 }
1285 };
1286
1287 // Create the standard streams
1288 _dup2_(stream.read_from_parent_, 0); // Input stream
1289 _dup2_(stream.write_to_parent_, 1); // Output stream
1290 _dup2_(stream.err_write_, 2); // Error stream
1291
1292 // Close the duped descriptors
1293 if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1294 subprocess_close(stream.read_from_parent_);
1295
1296 if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1297 subprocess_close(stream.write_to_parent_);
1298
1299 if (stream.err_write_ != -1 && stream.err_write_ > 2)
1300 subprocess_close(stream.err_write_);
1301
1302 // Replace the current image with the executable
1303 sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1304
1305 if (sys_ret == -1) throw OSError("execve failed", errno);
1306
1307 } catch (const OSError& exp) {
1308 // Just write the exception message
1309 // TODO: Give back stack trace ?
1310 std::string err_msg(exp.what());
1311 //ATTN: Can we do something on error here ?
1312 util::write_n(err_wr_pipe_, err_msg.c_str(), err_msg.length());
1313 }
1314
1315 // Calling application would not get this
1316 // exit failure
1317 _exit (EXIT_FAILURE);
1318 }
1319#endif
1320
1321
1323 {
1324#ifdef WIN32
1325 util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1326 this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1327 this->write_to_child_ = subprocess_fileno(this->input());
1328
1329 util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1330 this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1331 this->read_from_child_ = subprocess_fileno(this->output());
1332
1333 util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1334 this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1335 this->err_read_ = subprocess_fileno(this->error());
1336#else
1337
1338 if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
1339 if (read_from_child_ != -1) output(fdopen(read_from_child_, "rb"));
1340 if (err_read_ != -1) error(fdopen(err_read_, "rb"));
1341
1342 auto handles = {input(), output(), error()};
1343
1344 for (auto& h : handles) {
1345 if (h == nullptr) continue;
1346 setvbuf(h, nullptr, _IONBF, BUFSIZ);
1347 }
1348 #endif
1349 }
1350
1351 inline int Communication::send(const char* msg, size_t length)
1352 {
1353 if (stream_->input() == nullptr) return -1;
1354 return std::fwrite(msg, sizeof(char), length, stream_->input());
1355 }
1356
1357 inline int Communication::send(const std::vector<char>& msg)
1358 {
1359 return send(msg.data(), msg.size());
1360 }
1361
1362 inline std::pair<OutBuffer, ErrBuffer>
1363 Communication::communicate(const char* msg, size_t length)
1364 {
1365 // Optimization from subprocess.py
1366 // If we are using one pipe, or no pipe
1367 // at all, using select() or threads is unnecessary.
1368 auto hndls = {stream_->input(), stream_->output(), stream_->error()};
1369 int count = std::count(std::begin(hndls), std::end(hndls), nullptr);
1370 const int len_conv = length;
1371
1372 if (count >= 2) {
1373 OutBuffer obuf;
1374 ErrBuffer ebuf;
1375 if (stream_->input()) {
1376 if (msg) {
1377 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1378 if (wbytes < len_conv) {
1379 if (errno != EPIPE && errno != EINVAL) {
1380 throw OSError("fwrite error", errno);
1381 }
1382 }
1383 }
1384 // Close the input stream
1385 stream_->input_.reset();
1386 } else if (stream_->output()) {
1387 // Read till EOF
1388 // ATTN: This could be blocking, if the process
1389 // at the other end screws up, we get screwed as well
1390 obuf.add_cap(out_buf_cap_);
1391
1392 int rbytes = util::read_all(
1393 stream_->output(),
1394 obuf.buf);
1395
1396 if (rbytes == -1) {
1397 throw OSError("read to obuf failed", errno);
1398 }
1399
1400 obuf.length = rbytes;
1401 // Close the output stream
1402 stream_->output_.reset();
1403
1404 } else if (stream_->error()) {
1405 // Same screwness applies here as well
1406 ebuf.add_cap(err_buf_cap_);
1407
1408 int rbytes = util::read_atmost_n(
1409 stream_->error(),
1410 ebuf.buf.data(),
1411 ebuf.buf.size());
1412
1413 if (rbytes == -1) {
1414 throw OSError("read to ebuf failed", errno);
1415 }
1416
1417 ebuf.length = rbytes;
1418 // Close the error stream
1419 stream_->error_.reset();
1420 }
1421 return std::make_pair(std::move(obuf), std::move(ebuf));
1422 }
1423
1424 return communicate_threaded(msg, length);
1425 }
1426
1427
1428 inline std::pair<OutBuffer, ErrBuffer>
1429 Communication::communicate_threaded(const char* msg, size_t length)
1430 {
1431 OutBuffer obuf;
1432 ErrBuffer ebuf;
1433 std::future<int> out_fut, err_fut;
1434 const int length_conv = length;
1435
1436 if (stream_->output()) {
1437 obuf.add_cap(out_buf_cap_);
1438
1439 out_fut = std::async(std::launch::async,
1440 [&obuf, this] {
1441 return util::read_all(this->stream_->output(), obuf.buf);
1442 });
1443 }
1444 if (stream_->error()) {
1445 ebuf.add_cap(err_buf_cap_);
1446
1447 err_fut = std::async(std::launch::async,
1448 [&ebuf, this] {
1449 return util::read_all(this->stream_->error(), ebuf.buf);
1450 });
1451 }
1452 if (stream_->input()) {
1453 if (msg) {
1454 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1455 if (wbytes < length_conv) {
1456 if (errno != EPIPE && errno != EINVAL) {
1457 throw OSError("fwrite error", errno);
1458 }
1459 }
1460 }
1461 stream_->input_.reset();
1462 }
1463
1464 if (out_fut.valid()) {
1465 int res = out_fut.get();
1466 if (res != -1) obuf.length = res;
1467 else obuf.length = 0;
1468 }
1469 if (err_fut.valid()) {
1470 int res = err_fut.get();
1471 if (res != -1) ebuf.length = res;
1472 else ebuf.length = 0;
1473 }
1474
1475 return std::make_pair(std::move(obuf), std::move(ebuf));
1476 }
1477
1478} // end namespace detail
1479
1480}
1481
1482#endif // BITCOIN_UTIL_SUBPROCESS_H
int ret
int flags
Definition: bitcoin-tx.cpp:530
ArgsManager & args
Definition: bitcoind.cpp:280
Buffer(size_t cap)
Definition: subprocess.h:691
void add_cap(size_t cap)
Definition: subprocess.h:692
std::vector< char > buf
Definition: subprocess.h:695
CalledProcessError(const std::string &error_msg, int retcode)
Definition: subprocess.h:137
OSError(const std::string &err_msg, int err_code)
Definition: subprocess.h:156
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:972
void populate_c_argv()
Definition: subprocess.h:1035
detail::Streams stream_
Definition: subprocess.h:1004
std::pair< OutBuffer, ErrBuffer > communicate(const std::string &msg)
Definition: subprocess.h:979
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:959
Popen(std::initializer_list< const char * > cmd_args, Args &&...args)
Definition: subprocess.h:933
std::vector< char * > cargv_
Definition: subprocess.h:1018
Popen(std::vector< std::string > vargs_, Args &&... args)
Definition: subprocess.h:945
void execute_process() noexcept(false)
Definition: subprocess.h:1076
std::vector< std::string > vargs_
Definition: subprocess.h:1017
std::string exe_name_
Definition: subprocess.h:1014
int send(const std::vector< char > &msg)
Definition: subprocess.h:969
int send(const std::string &msg)
Definition: subprocess.h:966
std::pair< OutBuffer, ErrBuffer > communicate()
Definition: subprocess.h:991
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:984
int retcode() const noexcept
Definition: subprocess.h:955
int wait() noexcept(false)
Definition: subprocess.h:1043
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:961
int send(const char *msg, size_t length)
Definition: subprocess.h:963
Child(Popen *p, int err_wr_pipe)
Definition: subprocess.h:743
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:785
Communication(Communication &&)=default
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:784
int send(const char *msg, size_t length)
Definition: subprocess.h:1351
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:1363
std::pair< OutBuffer, ErrBuffer > communicate_threaded(const char *msg, size_t length)
Definition: subprocess.h:1429
Communication & operator=(const Communication &)=delete
Communication(const Communication &)=delete
Communication & operator=(Communication &&)=default
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:781
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:868
int send(const std::vector< char > &msg)
Definition: subprocess.h:862
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:855
Streams(Streams &&)=default
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:865
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:856
std::shared_ptr< FILE > output_
Definition: subprocess.h:875
std::shared_ptr< FILE > error_
Definition: subprocess.h:876
Streams & operator=(const Streams &)=delete
int send(const char *msg, size_t length)
Definition: subprocess.h:859
Streams(const Streams &)=delete
Streams & operator=(Streams &&)=default
std::shared_ptr< FILE > input_
Definition: subprocess.h:874
#define T(expected, seed, data)
Definition: basic.cpp:8
static int read_all(FILE *fp, std::vector< char > &buf)
Definition: subprocess.h:459
static int read_atmost_n(FILE *fp, char *buf, size_t read_upto)
Definition: subprocess.h:418
static void set_clo_on_exec(int fd, bool set=true)
Definition: subprocess.h:339
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.h:308
static std::pair< int, int > wait_for_child_exit(int pid)
Definition: subprocess.h:508
static std::pair< int, int > pipe_cloexec() noexcept(false)
Definition: subprocess.h:363
static int write_n(int fd, const char *buf, size_t length)
Definition: subprocess.h:391
static const size_t SP_MAX_ERR_BUF_SIZ
Definition: subprocess.h:113
static const size_t DEFAULT_BUF_CAP_BYTES
Definition: subprocess.h:118
void set_option(executable &&exe)
Definition: subprocess.h:1230
error(FILE *fp)
Definition: subprocess.h:649
error(IOTYPE typ)
Definition: subprocess.h:656
error(const char *filename)
Definition: subprocess.h:651
input(const char *filename)
Definition: subprocess.h:587
input(IOTYPE typ)
Definition: subprocess.h:592
input(FILE *fp)
Definition: subprocess.h:585
output(IOTYPE typ)
Definition: subprocess.h:625
output(const char *filename)
Definition: subprocess.h:620
output(FILE *fp)
Definition: subprocess.h:618
std::string arg_value
Definition: subprocess.h:540
string_arg(const char *arg)
Definition: subprocess.h:537
string_arg(std::string &&arg)
Definition: subprocess.h:538
string_arg(const std::string &arg)
Definition: subprocess.h:539
#define subprocess_close
Definition: subprocess.h:80
#define subprocess_write
Definition: subprocess.h:83
#define subprocess_fileno
Definition: subprocess.h:81
#define subprocess_open
Definition: subprocess.h:82
std::string SysErrorString(int err)
Return system error string from errno value.
Definition: syserror.cpp:18
static int count
assert(!tx.IsCoinBase())