Bitcoin Core 28.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
66extern "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
107namespace subprocess {
108
109// Max buffer size allocated on stack for read error
110// from pipe
111static 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
116static const size_t DEFAULT_BUF_CAP_BYTES = 8192;
117
118
119/*-----------------------------------------------
120 * EXCEPTION CLASSES
121 *-----------------------------------------------
122 */
123
131class CalledProcessError: public std::runtime_error
132{
133public:
135 CalledProcessError(const std::string& error_msg, int retcode):
136 std::runtime_error(error_msg), retcode(retcode)
137 {}
138};
139
140
151class OSError: public std::runtime_error
152{
153public:
154 OSError(const std::string& err_msg, int err_code):
155 std::runtime_error(err_msg + ": " + SysErrorString(err_code))
156 {}
157};
158
159//--------------------------------------------------------------------
160namespace 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
551enum IOTYPE {
555};
556
557//TODO: A common base/interface for below stream structures ??
558
570struct 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
605struct 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
636struct 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
679{
680public:
681 Buffer() = default;
682 explicit Buffer(size_t cap) { buf.resize(cap); }
683 void add_cap(size_t cap) { buf.resize(cap); }
684
685public:
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.
697class Popen;
698
699/*---------------------------------------------------
700 * DETAIL NAMESPACE
701 *---------------------------------------------------
702 */
703
704namespace 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
721private:
722 Popen* popen_ = nullptr;
723};
724
730class Child
731{
732public:
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
740private:
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.
748class Streams;
749
757{
758public:
759 Communication(Streams* stream): stream_(stream)
760 {}
761 void operator=(const Communication&) = delete;
762public:
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
773private:
774 std::pair<OutBuffer, ErrBuffer> communicate_threaded(
775 const char* msg, size_t length);
776
777private:
781};
782
783
784
795{
796public:
797 Streams():comm_(this) {}
798 void operator=(const Streams&) = delete;
799
800public:
801 void setup_comm_channels();
802
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
841public: /* 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
855public:// 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
884private:
886};
887
888} // end namespace detail
889
890
891
909class Popen
910{
911public:
913 friend class detail::Child;
914
915 template <typename... Args>
916 Popen(const std::string& cmd_args, Args&& ...args):
917 args_(cmd_args)
918 {
919 vargs_ = util::split(cmd_args);
920 init_args(std::forward<Args>(args)...);
921
922 // Setup the communication channels of the Popen class
924
926 }
927
928 template <typename... Args>
929 Popen(std::initializer_list<const char*> cmd_args, Args&& ...args)
930 {
931 vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end());
932 init_args(std::forward<Args>(args)...);
933
934 // Setup the communication channels of the Popen class
936
938 }
939
940 template <typename... Args>
941 Popen(std::vector<std::string> vargs_, Args &&... args) : vargs_(vargs_)
942 {
943 init_args(std::forward<Args>(args)...);
944
945 // Setup the communication channels of the Popen class
947
949 }
950
951 int retcode() const noexcept { return retcode_; }
952
953 int wait() noexcept(false);
954
955 void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); }
956
957 void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); }
958
959 int send(const char* msg, size_t length)
960 { return stream_.send(msg, length); }
961
962 int send(const std::string& msg)
963 { return send(msg.c_str(), msg.size()); }
964
965 int send(const std::vector<char>& msg)
966 { return stream_.send(msg); }
967
968 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
969 {
970 auto res = stream_.communicate(msg, length);
971 retcode_ = wait();
972 return res;
973 }
974
975 std::pair<OutBuffer, ErrBuffer> communicate(const std::string& msg)
976 {
977 return communicate(msg.c_str(), msg.size());
978 }
979
980 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
981 {
982 auto res = stream_.communicate(msg);
983 retcode_ = wait();
984 return res;
985 }
986
987 std::pair<OutBuffer, ErrBuffer> communicate()
988 {
989 return communicate(nullptr, 0);
990 }
991
992private:
993 template <typename F, typename... Args>
994 void init_args(F&& farg, Args&&... args);
995 void init_args();
996 void populate_c_argv();
997 void execute_process() noexcept(false);
998
999private:
1000 detail::Streams stream_;
1001
1002#ifdef __USING_WINDOWS__
1003 HANDLE process_handle_;
1004 std::future<void> cleanup_future_;
1005#endif
1006
1007 std::string exe_name_;
1008
1009 // Command in string format
1010 std::string args_;
1011 // Command provided as sequence
1012 std::vector<std::string> vargs_;
1013 std::vector<char*> cargv_;
1014
1015 // Pid of the child process
1016 int child_pid_ = -1;
1017
1018 int retcode_ = -1;
1019};
1020
1021inline void Popen::init_args() {
1023}
1024
1025template <typename F, typename... Args>
1026inline void Popen::init_args(F&& farg, Args&&... args)
1027{
1028 detail::ArgumentDeducer argd(this);
1029 argd.set_option(std::forward<F>(farg));
1030 init_args(std::forward<Args>(args)...);
1031}
1032
1034{
1035 cargv_.clear();
1036 cargv_.reserve(vargs_.size() + 1);
1037 for (auto& arg : vargs_) cargv_.push_back(&arg[0]);
1038 cargv_.push_back(nullptr);
1039}
1040
1041inline int Popen::wait() noexcept(false)
1042{
1043#ifdef __USING_WINDOWS__
1044 int ret = WaitForSingleObject(process_handle_, INFINITE);
1045
1046 return 0;
1047#else
1048 int ret, status;
1049 std::tie(ret, status) = util::wait_for_child_exit(child_pid_);
1050 if (ret == -1) {
1051 if (errno != ECHILD) throw OSError("waitpid failed", errno);
1052 return 0;
1053 }
1054 if (WIFEXITED(status)) return WEXITSTATUS(status);
1055 if (WIFSIGNALED(status)) return WTERMSIG(status);
1056 else return 255;
1057
1058 return 0;
1059#endif
1060}
1061
1062inline void Popen::execute_process() noexcept(false)
1063{
1064#ifdef __USING_WINDOWS__
1065 if (exe_name_.length()) {
1066 this->vargs_.insert(this->vargs_.begin(), this->exe_name_);
1067 this->populate_c_argv();
1068 }
1069 this->exe_name_ = vargs_[0];
1070
1071 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
1072 std::wstring argument;
1073 std::wstring command_line;
1074
1075 for (auto arg : this->vargs_) {
1076 argument = converter.from_bytes(arg);
1077 util::quote_argument(argument, command_line, false);
1078 command_line += L" ";
1079 }
1080
1081 // CreateProcessW can modify szCmdLine so we allocate needed memory
1082 wchar_t *szCmdline = new wchar_t[command_line.size() + 1];
1083 wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
1084 PROCESS_INFORMATION piProcInfo;
1085 STARTUPINFOW siStartInfo;
1086 BOOL bSuccess = FALSE;
1087 DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
1088
1089 // Set up members of the PROCESS_INFORMATION structure.
1090 ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
1091
1092 // Set up members of the STARTUPINFOW structure.
1093 // This structure specifies the STDIN and STDOUT handles for redirection.
1094
1095 ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW));
1096 siStartInfo.cb = sizeof(STARTUPINFOW);
1097
1098 siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
1099 siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
1100 siStartInfo.hStdInput = this->stream_.g_hChildStd_IN_Rd;
1101
1102 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
1103
1104 // Create the child process.
1105 bSuccess = CreateProcessW(NULL,
1106 szCmdline, // command line
1107 NULL, // process security attributes
1108 NULL, // primary thread security attributes
1109 TRUE, // handles are inherited
1110 creation_flags, // creation flags
1111 NULL, // use parent's environment
1112 NULL, // use parent's current directory
1113 &siStartInfo, // STARTUPINFOW pointer
1114 &piProcInfo); // receives PROCESS_INFORMATION
1115
1116 // If an error occurs, exit the application.
1117 if (!bSuccess) {
1118 DWORD errorMessageID = ::GetLastError();
1119 throw CalledProcessError("CreateProcess failed: " + util::get_last_error(errorMessageID), errorMessageID);
1120 }
1121
1122 CloseHandle(piProcInfo.hThread);
1123
1124 /*
1125 TODO: use common apis to close linux handles
1126 */
1127
1128 this->process_handle_ = piProcInfo.hProcess;
1129
1130 this->cleanup_future_ = std::async(std::launch::async, [this] {
1131 WaitForSingleObject(this->process_handle_, INFINITE);
1132
1133 CloseHandle(this->stream_.g_hChildStd_ERR_Wr);
1134 CloseHandle(this->stream_.g_hChildStd_OUT_Wr);
1135 CloseHandle(this->stream_.g_hChildStd_IN_Rd);
1136 });
1137
1138/*
1139 NOTE: In the linux version, there is a check to make sure that the process
1140 has been started. Here, we do nothing because CreateProcess will throw
1141 if we fail to create the process.
1142*/
1143
1144
1145#else
1146
1147 int err_rd_pipe, err_wr_pipe;
1148 std::tie(err_rd_pipe, err_wr_pipe) = util::pipe_cloexec();
1149
1150 if (exe_name_.length()) {
1151 vargs_.insert(vargs_.begin(), exe_name_);
1153 }
1154 exe_name_ = vargs_[0];
1155
1156 child_pid_ = fork();
1157
1158 if (child_pid_ < 0) {
1159 close(err_rd_pipe);
1160 close(err_wr_pipe);
1161 throw OSError("fork failed", errno);
1162 }
1163
1164 if (child_pid_ == 0)
1165 {
1166 // Close descriptors belonging to parent
1168
1169 //Close the read end of the error pipe
1170 close(err_rd_pipe);
1171
1172 detail::Child chld(this, err_wr_pipe);
1173 chld.execute_child();
1174 }
1175 else
1176 {
1177 close (err_wr_pipe);// close child side of pipe, else get stuck in read below
1178
1180
1181 try {
1182 char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1183
1184 int read_bytes = util::read_atmost_n(
1185 fdopen(err_rd_pipe, "r"),
1186 err_buf,
1188 close(err_rd_pipe);
1189
1190 if (read_bytes || strlen(err_buf)) {
1191 // Call waitpid to reap the child process
1192 // waitpid suspends the calling process until the
1193 // child terminates.
1194 int retcode = wait();
1195
1196 // Throw whatever information we have about child failure
1197 throw CalledProcessError(err_buf, retcode);
1198 }
1199 } catch (std::exception& exp) {
1201 throw;
1202 }
1203
1204 }
1205#endif
1206}
1207
1208namespace detail {
1209
1211 popen_->exe_name_ = std::move(exe.arg_value);
1212 }
1213
1215 if (inp.rd_ch_ != -1) popen_->stream_.read_from_parent_ = inp.rd_ch_;
1216 if (inp.wr_ch_ != -1) popen_->stream_.write_to_child_ = inp.wr_ch_;
1217 }
1218
1220 if (out.wr_ch_ != -1) popen_->stream_.write_to_parent_ = out.wr_ch_;
1221 if (out.rd_ch_ != -1) popen_->stream_.read_from_child_ = out.rd_ch_;
1222 }
1223
1225 if (err.deferred_) {
1228 } else {
1229 throw std::runtime_error("Set output before redirecting error to output");
1230 }
1231 }
1232 if (err.wr_ch_ != -1) popen_->stream_.err_write_ = err.wr_ch_;
1233 if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1234 }
1235
1236
1237 inline void Child::execute_child() {
1238#ifndef __USING_WINDOWS__
1239 int sys_ret = -1;
1240 auto& stream = parent_->stream_;
1241
1242 try {
1243 if (stream.write_to_parent_ == 0)
1244 stream.write_to_parent_ = dup(stream.write_to_parent_);
1245
1246 if (stream.err_write_ == 0 || stream.err_write_ == 1)
1247 stream.err_write_ = dup(stream.err_write_);
1248
1249 // Make the child owned descriptors as the
1250 // stdin, stdout and stderr for the child process
1251 auto _dup2_ = [](int fd, int to_fd) {
1252 if (fd == to_fd) {
1253 // dup2 syscall does not reset the
1254 // CLOEXEC flag if the descriptors
1255 // provided to it are same.
1256 // But, we need to reset the CLOEXEC
1257 // flag as the provided descriptors
1258 // are now going to be the standard
1259 // input, output and error
1260 util::set_clo_on_exec(fd, false);
1261 } else if(fd != -1) {
1262 int res = dup2(fd, to_fd);
1263 if (res == -1) throw OSError("dup2 failed", errno);
1264 }
1265 };
1266
1267 // Create the standard streams
1268 _dup2_(stream.read_from_parent_, 0); // Input stream
1269 _dup2_(stream.write_to_parent_, 1); // Output stream
1270 _dup2_(stream.err_write_, 2); // Error stream
1271
1272 // Close the duped descriptors
1273 if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1274 close(stream.read_from_parent_);
1275
1276 if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1277 close(stream.write_to_parent_);
1278
1279 if (stream.err_write_ != -1 && stream.err_write_ > 2)
1280 close(stream.err_write_);
1281
1282 // Replace the current image with the executable
1283 sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1284
1285 if (sys_ret == -1) throw OSError("execve failed", errno);
1286
1287 } catch (const OSError& exp) {
1288 // Just write the exception message
1289 // TODO: Give back stack trace ?
1290 std::string err_msg(exp.what());
1291 //ATTN: Can we do something on error here ?
1292 util::write_n(err_wr_pipe_, err_msg.c_str(), err_msg.length());
1293 }
1294
1295 // Calling application would not get this
1296 // exit failure
1297 _exit (EXIT_FAILURE);
1298#endif
1299 }
1300
1301
1303 {
1304#ifdef __USING_WINDOWS__
1305 util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1306 this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1307 this->write_to_child_ = _fileno(this->input());
1308
1309 util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1310 this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1311 this->read_from_child_ = _fileno(this->output());
1312
1313 util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1314 this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1315 this->err_read_ = _fileno(this->error());
1316#else
1317
1318 if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
1319 if (read_from_child_ != -1) output(fdopen(read_from_child_, "rb"));
1320 if (err_read_ != -1) error(fdopen(err_read_, "rb"));
1321
1322 auto handles = {input(), output(), error()};
1323
1324 for (auto& h : handles) {
1325 if (h == nullptr) continue;
1326 setvbuf(h, nullptr, _IONBF, BUFSIZ);
1327 }
1328 #endif
1329 }
1330
1331 inline int Communication::send(const char* msg, size_t length)
1332 {
1333 if (stream_->input() == nullptr) return -1;
1334 return std::fwrite(msg, sizeof(char), length, stream_->input());
1335 }
1336
1337 inline int Communication::send(const std::vector<char>& msg)
1338 {
1339 return send(msg.data(), msg.size());
1340 }
1341
1342 inline std::pair<OutBuffer, ErrBuffer>
1343 Communication::communicate(const char* msg, size_t length)
1344 {
1345 // Optimization from subprocess.py
1346 // If we are using one pipe, or no pipe
1347 // at all, using select() or threads is unnecessary.
1348 auto hndls = {stream_->input(), stream_->output(), stream_->error()};
1349 int count = std::count(std::begin(hndls), std::end(hndls), nullptr);
1350 const int len_conv = length;
1351
1352 if (count >= 2) {
1353 OutBuffer obuf;
1354 ErrBuffer ebuf;
1355 if (stream_->input()) {
1356 if (msg) {
1357 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1358 if (wbytes < len_conv) {
1359 if (errno != EPIPE && errno != EINVAL) {
1360 throw OSError("fwrite error", errno);
1361 }
1362 }
1363 }
1364 // Close the input stream
1365 stream_->input_.reset();
1366 } else if (stream_->output()) {
1367 // Read till EOF
1368 // ATTN: This could be blocking, if the process
1369 // at the other end screws up, we get screwed as well
1370 obuf.add_cap(out_buf_cap_);
1371
1372 int rbytes = util::read_all(
1373 stream_->output(),
1374 obuf.buf);
1375
1376 if (rbytes == -1) {
1377 throw OSError("read to obuf failed", errno);
1378 }
1379
1380 obuf.length = rbytes;
1381 // Close the output stream
1382 stream_->output_.reset();
1383
1384 } else if (stream_->error()) {
1385 // Same screwness applies here as well
1386 ebuf.add_cap(err_buf_cap_);
1387
1388 int rbytes = util::read_atmost_n(
1389 stream_->error(),
1390 ebuf.buf.data(),
1391 ebuf.buf.size());
1392
1393 if (rbytes == -1) {
1394 throw OSError("read to ebuf failed", errno);
1395 }
1396
1397 ebuf.length = rbytes;
1398 // Close the error stream
1399 stream_->error_.reset();
1400 }
1401 return std::make_pair(std::move(obuf), std::move(ebuf));
1402 }
1403
1404 return communicate_threaded(msg, length);
1405 }
1406
1407
1408 inline std::pair<OutBuffer, ErrBuffer>
1409 Communication::communicate_threaded(const char* msg, size_t length)
1410 {
1411 OutBuffer obuf;
1412 ErrBuffer ebuf;
1413 std::future<int> out_fut, err_fut;
1414 const int length_conv = length;
1415
1416 if (stream_->output()) {
1417 obuf.add_cap(out_buf_cap_);
1418
1419 out_fut = std::async(std::launch::async,
1420 [&obuf, this] {
1421 return util::read_all(this->stream_->output(), obuf.buf);
1422 });
1423 }
1424 if (stream_->error()) {
1425 ebuf.add_cap(err_buf_cap_);
1426
1427 err_fut = std::async(std::launch::async,
1428 [&ebuf, this] {
1429 return util::read_all(this->stream_->error(), ebuf.buf);
1430 });
1431 }
1432 if (stream_->input()) {
1433 if (msg) {
1434 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1435 if (wbytes < length_conv) {
1436 if (errno != EPIPE && errno != EINVAL) {
1437 throw OSError("fwrite error", errno);
1438 }
1439 }
1440 }
1441 stream_->input_.reset();
1442 }
1443
1444 if (out_fut.valid()) {
1445 int res = out_fut.get();
1446 if (res != -1) obuf.length = res;
1447 else obuf.length = 0;
1448 }
1449 if (err_fut.valid()) {
1450 int res = err_fut.get();
1451 if (res != -1) ebuf.length = res;
1452 else ebuf.length = 0;
1453 }
1454
1455 return std::make_pair(std::move(obuf), std::move(ebuf));
1456 }
1457
1458} // end namespace detail
1459
1460}
1461
1462#endif // BITCOIN_UTIL_SUBPROCESS_H
int ret
int flags
Definition: bitcoin-tx.cpp:536
ArgsManager & args
Definition: bitcoind.cpp:277
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
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:968
void populate_c_argv()
Definition: subprocess.h:1033
detail::Streams stream_
Definition: subprocess.h:1000
std::pair< OutBuffer, ErrBuffer > communicate(const std::string &msg)
Definition: subprocess.h:975
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:955
Popen(std::initializer_list< const char * > cmd_args, Args &&...args)
Definition: subprocess.h:929
std::vector< char * > cargv_
Definition: subprocess.h:1013
Popen(std::vector< std::string > vargs_, Args &&... args)
Definition: subprocess.h:941
void execute_process() noexcept(false)
Definition: subprocess.h:1062
std::vector< std::string > vargs_
Definition: subprocess.h:1012
std::string exe_name_
Definition: subprocess.h:1007
int send(const std::vector< char > &msg)
Definition: subprocess.h:965
int send(const std::string &msg)
Definition: subprocess.h:962
std::pair< OutBuffer, ErrBuffer > communicate()
Definition: subprocess.h:987
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:980
int retcode() const noexcept
Definition: subprocess.h:951
Popen(const std::string &cmd_args, Args &&...args)
Definition: subprocess.h:916
int wait() noexcept(false)
Definition: subprocess.h:1041
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:957
int send(const char *msg, size_t length)
Definition: subprocess.h:959
std::string args_
Definition: subprocess.h:1010
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:1331
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:1343
std::pair< OutBuffer, ErrBuffer > communicate_threaded(const char *msg, size_t length)
Definition: subprocess.h:1409
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:767
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:851
int send(const std::vector< char > &msg)
Definition: subprocess.h:845
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:838
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:848
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::shared_ptr< FILE > input_
Definition: subprocess.h:857
#define T(expected, seed, data)
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 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 std::pair< int, int > wait_for_child_exit(int pid)
Definition: subprocess.h:499
static std::pair< int, int > pipe_cloexec() noexcept(false)
Definition: subprocess.h:354
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:1210
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:19
static int count
assert(!tx.IsCoinBase())