Bitcoin Core 29.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/fs.h>
40#include <util/strencodings.h>
41#include <util/syserror.h>
42
43#include <algorithm>
44#include <cassert>
45#include <csignal>
46#include <cstdio>
47#include <cstdlib>
48#include <cstring>
49#include <exception>
50#include <future>
51#include <initializer_list>
52#include <iostream>
53#include <locale>
54#include <map>
55#include <memory>
56#include <sstream>
57#include <string>
58#include <vector>
59
60#if (defined _MSC_VER) || (defined __MINGW32__)
61 #define __USING_WINDOWS__
62#endif
63
64#ifdef __USING_WINDOWS__
65 #include <codecvt>
66#endif
67
68extern "C" {
69#ifdef __USING_WINDOWS__
70 #include <windows.h>
71 #include <io.h>
72 #include <cwchar>
73#else
74 #include <sys/wait.h>
75 #include <unistd.h>
76#endif
77 #include <csignal>
78 #include <fcntl.h>
79 #include <sys/types.h>
80}
81
82// The Microsoft C++ compiler issues deprecation warnings
83// for the standard POSIX function names.
84// Its preferred implementations have a leading underscore.
85// See: https://learn.microsoft.com/en-us/cpp/c-runtime-library/compatibility.
86#if (defined _MSC_VER)
87 #define subprocess_close _close
88 #define subprocess_fileno _fileno
89 #define subprocess_open _open
90 #define subprocess_write _write
91#else
92 #define subprocess_close close
93 #define subprocess_fileno fileno
94 #define subprocess_open open
95 #define subprocess_write write
96#endif
97
121namespace subprocess {
122
123// Max buffer size allocated on stack for read error
124// from pipe
125static const size_t SP_MAX_ERR_BUF_SIZ = 1024;
126
127// Default buffer capacity for OutBuffer and ErrBuffer.
128// If the data exceeds this capacity, the buffer size is grown
129// by 1.5 times its previous capacity
130static const size_t DEFAULT_BUF_CAP_BYTES = 8192;
131
132
133/*-----------------------------------------------
134 * EXCEPTION CLASSES
135 *-----------------------------------------------
136 */
137
145class CalledProcessError: public std::runtime_error
146{
147public:
149 CalledProcessError(const std::string& error_msg, int retcode):
150 std::runtime_error(error_msg), retcode(retcode)
151 {}
152};
153
154
165class OSError: public std::runtime_error
166{
167public:
168 OSError(const std::string& err_msg, int err_code):
169 std::runtime_error(err_msg + ": " + SysErrorString(err_code))
170 {}
171};
172
173//--------------------------------------------------------------------
174namespace util
175{
176#ifdef __USING_WINDOWS__
177 inline void quote_argument(const std::wstring &argument, std::wstring &command_line,
178 bool force)
179 {
180 //
181 // Unless we're told otherwise, don't quote unless we actually
182 // need to do so --- hopefully avoid problems if programs won't
183 // parse quotes properly
184 //
185
186 if (force == false && argument.empty() == false &&
187 argument.find_first_of(L" \t\n\v") == argument.npos) {
188 command_line.append(argument);
189 }
190 else {
191 command_line.push_back(L'"');
192
193 for (auto it = argument.begin();; ++it) {
194 unsigned number_backslashes = 0;
195
196 while (it != argument.end() && *it == L'\\') {
197 ++it;
198 ++number_backslashes;
199 }
200
201 if (it == argument.end()) {
202
203 //
204 // Escape all backslashes, but let the terminating
205 // double quotation mark we add below be interpreted
206 // as a metacharacter.
207 //
208
209 command_line.append(number_backslashes * 2, L'\\');
210 break;
211 }
212 else if (*it == L'"') {
213
214 //
215 // Escape all backslashes and the following
216 // double quotation mark.
217 //
218
219 command_line.append(number_backslashes * 2 + 1, L'\\');
220 command_line.push_back(*it);
221 }
222 else {
223
224 //
225 // Backslashes aren't special here.
226 //
227
228 command_line.append(number_backslashes, L'\\');
229 command_line.push_back(*it);
230 }
231 }
232
233 command_line.push_back(L'"');
234 }
235 }
236
237 inline std::string get_last_error(DWORD errorMessageID)
238 {
239 if (errorMessageID == 0)
240 return std::string();
241
242 LPSTR messageBuffer = nullptr;
243 size_t size = FormatMessageA(
244 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
245 FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
246 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
247 (LPSTR)&messageBuffer, 0, NULL);
248
249 std::string message(messageBuffer, size);
250
251 LocalFree(messageBuffer);
252
253 return message;
254 }
255
256 inline FILE *file_from_handle(HANDLE h, const char *mode)
257 {
258 int md;
259 if (!mode) {
260 throw OSError("invalid_mode", 0);
261 }
262
263 if (mode[0] == 'w') {
264 md = _O_WRONLY;
265 }
266 else if (mode[0] == 'r') {
267 md = _O_RDONLY;
268 }
269 else {
270 throw OSError("file_from_handle", 0);
271 }
272
273 int os_fhandle = _open_osfhandle((intptr_t)h, md);
274 if (os_fhandle == -1) {
275 CloseHandle(h);
276 throw OSError("_open_osfhandle", 0);
277 }
278
279 FILE *fp = _fdopen(os_fhandle, mode);
280 if (fp == 0) {
281 subprocess_close(os_fhandle);
282 throw OSError("_fdopen", 0);
283 }
284
285 return fp;
286 }
287
288 inline void configure_pipe(HANDLE* read_handle, HANDLE* write_handle, HANDLE* child_handle)
289 {
290 SECURITY_ATTRIBUTES saAttr;
291
292 // Set the bInheritHandle flag so pipe handles are inherited.
293 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
294 saAttr.bInheritHandle = TRUE;
295 saAttr.lpSecurityDescriptor = NULL;
296
297 // Create a pipe for the child process's STDIN.
298 if (!CreatePipe(read_handle, write_handle, &saAttr,0))
299 throw OSError("CreatePipe", 0);
300
301 // Ensure the write handle to the pipe for STDIN is not inherited.
302 if (!SetHandleInformation(*child_handle, HANDLE_FLAG_INHERIT, 0))
303 throw OSError("SetHandleInformation", 0);
304 }
305#endif
306
316 static inline std::vector<std::string>
317 split(const std::string& str, const std::string& delims=" \t")
318 {
319 std::vector<std::string> res;
320 size_t init = 0;
321
322 while (true) {
323 auto pos = str.find_first_of(delims, init);
324 if (pos == std::string::npos) {
325 res.emplace_back(str.substr(init, str.length()));
326 break;
327 }
328 res.emplace_back(str.substr(init, pos - init));
329 pos++;
330 init = pos;
331 }
332
333 return res;
334 }
335
336
337#ifndef __USING_WINDOWS__
347 static inline
348 void set_clo_on_exec(int fd, bool set = true)
349 {
350 int flags = fcntl(fd, F_GETFD, 0);
351 if (flags == -1) {
352 throw OSError("fcntl F_GETFD failed", errno);
353 }
354 if (set) flags |= FD_CLOEXEC;
355 else flags &= ~FD_CLOEXEC;
356 if (fcntl(fd, F_SETFD, flags) == -1) {
357 throw OSError("fcntl F_SETFD failed", errno);
358 }
359 }
360
361
371 static inline
372 std::pair<int, int> pipe_cloexec() noexcept(false)
373 {
374 int pipe_fds[2];
375 int res = pipe(pipe_fds);
376 if (res) {
377 throw OSError("pipe failure", errno);
378 }
379
380 set_clo_on_exec(pipe_fds[0]);
381 set_clo_on_exec(pipe_fds[1]);
382
383 return std::make_pair(pipe_fds[0], pipe_fds[1]);
384 }
385#endif
386
387
399 static inline
400 int write_n(int fd, const char* buf, size_t length)
401 {
402 size_t nwritten = 0;
403 while (nwritten < length) {
404 int written = subprocess_write(fd, buf + nwritten, length - nwritten);
405 if (written == -1) return -1;
406 nwritten += written;
407 }
408 return nwritten;
409 }
410
411
426 static inline
427 int read_atmost_n(FILE* fp, char* buf, size_t read_upto)
428 {
429#ifdef __USING_WINDOWS__
430 return (int)fread(buf, 1, read_upto, fp);
431#else
432 int fd = subprocess_fileno(fp);
433 int rbytes = 0;
434 int eintr_cnter = 0;
435
436 while (1) {
437 int read_bytes = read(fd, buf + rbytes, read_upto - rbytes);
438 if (read_bytes == -1) {
439 if (errno == EINTR) {
440 if (eintr_cnter >= 50) return -1;
441 eintr_cnter++;
442 continue;
443 }
444 return -1;
445 }
446 if (read_bytes == 0) return rbytes;
447
448 rbytes += read_bytes;
449 }
450 return rbytes;
451#endif
452 }
453
454
468 static inline int read_all(FILE* fp, std::vector<char>& buf)
469 {
470 auto buffer = buf.data();
471 int total_bytes_read = 0;
472 int fill_sz = buf.size();
473
474 while (1) {
475 const int rd_bytes = read_atmost_n(fp, buffer, fill_sz);
476
477 if (rd_bytes == -1) { // Read finished
478 if (total_bytes_read == 0) return -1;
479 break;
480
481 } else if (rd_bytes == fill_sz) { // Buffer full
482 const auto orig_sz = buf.size();
483 const auto new_sz = orig_sz * 2;
484 buf.resize(new_sz);
485 fill_sz = new_sz - orig_sz;
486
487 //update the buffer pointer
488 buffer = buf.data();
489 total_bytes_read += rd_bytes;
490 buffer += total_bytes_read;
491
492 } else { // Partial data ? Continue reading
493 total_bytes_read += rd_bytes;
494 fill_sz -= rd_bytes;
495 break;
496 }
497 }
498 buf.erase(buf.begin()+total_bytes_read, buf.end()); // remove extra nulls
499 return total_bytes_read;
500 }
501
502#ifndef __USING_WINDOWS__
516 static inline
517 std::pair<int, int> wait_for_child_exit(int pid)
518 {
519 int status = 0;
520 int ret = -1;
521 while (1) {
522 ret = waitpid(pid, &status, 0);
523 if (ret == -1) break;
524 if (ret == 0) continue;
525 return std::make_pair(ret, status);
526 }
527
528 return std::make_pair(ret, status);
529 }
530#endif
531
532} // end namespace util
533
534
535
536/* -------------------------------
537 * Popen Arguments
538 * -------------------------------
539 */
540
550struct close_fds {
551 explicit close_fds(bool c): close_all(c) {}
552 bool close_all = false;
553};
554
559{
560 string_arg(const char* arg): arg_value(arg) {}
561 string_arg(std::string&& arg): arg_value(std::move(arg)) {}
562 string_arg(const std::string& arg): arg_value(arg) {}
563 std::string arg_value;
564};
565
575{
576 template <typename T>
577 executable(T&& arg): string_arg(std::forward<T>(arg)) {}
578};
579
583enum IOTYPE {
587};
588
589//TODO: A common base/interface for below stream structures ??
590
602struct input
603{
604 // For an already existing file descriptor.
605 explicit input(int fd): rd_ch_(fd) {}
606
607 // FILE pointer.
608 explicit input (FILE* fp):input(subprocess_fileno(fp)) { assert(fp); }
609
610 explicit input(const char* filename) {
611 int fd = subprocess_open(filename, O_RDONLY);
612 if (fd == -1) throw OSError("File not found: ", errno);
613 rd_ch_ = fd;
614 }
615 explicit input(IOTYPE typ) {
616 assert (typ == PIPE && "STDOUT/STDERR not allowed");
617#ifndef __USING_WINDOWS__
618 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
619#endif
620 }
621
622 int rd_ch_ = -1;
623 int wr_ch_ = -1;
624};
625
626
637struct output
638{
639 explicit output(int fd): wr_ch_(fd) {}
640
641 explicit output (FILE* fp):output(subprocess_fileno(fp)) { assert(fp); }
642
643 explicit output(const char* filename) {
644 int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
645 if (fd == -1) throw OSError("File not found: ", errno);
646 wr_ch_ = fd;
647 }
648 explicit output(IOTYPE typ) {
649 assert (typ == PIPE && "STDOUT/STDERR not allowed");
650#ifndef __USING_WINDOWS__
651 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
652#endif
653 }
654
655 int rd_ch_ = -1;
656 int wr_ch_ = -1;
657};
658
659
668struct error
669{
670 explicit error(int fd): wr_ch_(fd) {}
671
672 explicit error(FILE* fp):error(subprocess_fileno(fp)) { assert(fp); }
673
674 explicit error(const char* filename) {
675 int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
676 if (fd == -1) throw OSError("File not found: ", errno);
677 wr_ch_ = fd;
678 }
679 explicit error(IOTYPE typ) {
680 assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed");
681 if (typ == PIPE) {
682#ifndef __USING_WINDOWS__
683 std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
684#endif
685 } else {
686 // Need to defer it till we have checked all arguments
687 deferred_ = true;
688 }
689 }
690
691 bool deferred_ = false;
692 int rd_ch_ = -1;
693 int wr_ch_ = -1;
694};
695
696// ~~~~ End Popen Args ~~~~
697
698
711{
712public:
713 Buffer() = default;
714 explicit Buffer(size_t cap) { buf.resize(cap); }
715 void add_cap(size_t cap) { buf.resize(cap); }
716
717public:
718 std::vector<char> buf;
719 size_t length = 0;
720};
721
722// Buffer for storing output written to output fd
724// Buffer for storing output written to error fd
726
727
728// Fwd Decl.
729class Popen;
730
731/*---------------------------------------------------
732 * DETAIL NAMESPACE
733 *---------------------------------------------------
734 */
735
736namespace detail {
745{
747
748 void set_option(executable&& exe);
749 void set_option(input&& inp);
750 void set_option(output&& out);
751 void set_option(error&& err);
752 void set_option(close_fds&& cfds);
753
754private:
755 Popen* popen_ = nullptr;
756};
757
763class Child
764{
765public:
766 Child(Popen* p, int err_wr_pipe):
767 parent_(p),
768 err_wr_pipe_(err_wr_pipe)
769 {}
770
771 void execute_child();
772
773private:
774 // Lets call it parent even though
775 // technically a bit incorrect
776 Popen* parent_ = nullptr;
777 int err_wr_pipe_ = -1;
778};
779
780// Fwd Decl.
781class Streams;
782
790{
791public:
792 Communication(Streams* stream): stream_(stream)
793 {}
794 Communication(const Communication&) = delete;
798public:
799 int send(const char* msg, size_t length);
800 int send(const std::vector<char>& msg);
801
802 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length);
803 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
804 { return communicate(msg.data(), msg.size()); }
805
806 void set_out_buf_cap(size_t cap) { out_buf_cap_ = cap; }
807 void set_err_buf_cap(size_t cap) { err_buf_cap_ = cap; }
808
809private:
810 std::pair<OutBuffer, ErrBuffer> communicate_threaded(
811 const char* msg, size_t length);
812
813private:
817};
818
819
820
831{
832public:
833 Streams():comm_(this) {}
834 Streams(const Streams&) = delete;
835 Streams& operator=(const Streams&) = delete;
836 Streams(Streams&&) = default;
837 Streams& operator=(Streams&&) = default;
838
839public:
840 void setup_comm_channels();
841
843 {
844 if (write_to_child_ != -1 && read_from_parent_ != -1) {
846 }
847 if (write_to_parent_ != -1 && read_from_child_ != -1) {
849 }
850 if (err_write_ != -1 && err_read_ != -1) {
852 }
853 }
854
856 {
860 }
861
863 {
867 }
868
869 FILE* input() { return input_.get(); }
870 FILE* output() { return output_.get(); }
871 FILE* error() { return error_.get(); }
872
873 void input(FILE* fp) { input_.reset(fp, fclose); }
874 void output(FILE* fp) { output_.reset(fp, fclose); }
875 void error(FILE* fp) { error_.reset(fp, fclose); }
876
877 void set_out_buf_cap(size_t cap) { comm_.set_out_buf_cap(cap); }
878 void set_err_buf_cap(size_t cap) { comm_.set_err_buf_cap(cap); }
879
880public: /* Communication forwarding API's */
881 int send(const char* msg, size_t length)
882 { return comm_.send(msg, length); }
883
884 int send(const std::vector<char>& msg)
885 { return comm_.send(msg); }
886
887 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
888 { return comm_.communicate(msg, length); }
889
890 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
891 { return comm_.communicate(msg); }
892
893
894public:// Yes they are public
895
896 std::shared_ptr<FILE> input_ = nullptr;
897 std::shared_ptr<FILE> output_ = nullptr;
898 std::shared_ptr<FILE> error_ = nullptr;
899
900#ifdef __USING_WINDOWS__
901 HANDLE g_hChildStd_IN_Rd = nullptr;
902 HANDLE g_hChildStd_IN_Wr = nullptr;
903 HANDLE g_hChildStd_OUT_Rd = nullptr;
904 HANDLE g_hChildStd_OUT_Wr = nullptr;
905 HANDLE g_hChildStd_ERR_Rd = nullptr;
906 HANDLE g_hChildStd_ERR_Wr = nullptr;
907#endif
908
909 // Pipes for communicating with child
910
911 // Emulates stdin
912 int write_to_child_ = -1; // Parent owned descriptor
913 int read_from_parent_ = -1; // Child owned descriptor
914
915 // Emulates stdout
916 int write_to_parent_ = -1; // Child owned descriptor
917 int read_from_child_ = -1; // Parent owned descriptor
918
919 // Emulates stderr
920 int err_write_ = -1; // Write error to parent (Child owned)
921 int err_read_ = -1; // Read error from child (Parent owned)
922
923private:
925};
926
927} // end namespace detail
928
929
930
948class Popen
949{
950public:
952 friend class detail::Child;
953
954 template <typename... Args>
955 Popen(const std::string& cmd_args, Args&& ...args):
956 args_(cmd_args)
957 {
958 vargs_ = util::split(cmd_args);
959 init_args(std::forward<Args>(args)...);
960
961 // Setup the communication channels of the Popen class
963
965 }
966
967 template <typename... Args>
968 Popen(std::initializer_list<const char*> cmd_args, Args&& ...args)
969 {
970 vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end());
971 init_args(std::forward<Args>(args)...);
972
973 // Setup the communication channels of the Popen class
975
977 }
978
979 template <typename... Args>
980 Popen(std::vector<std::string> vargs_, Args &&... args) : vargs_(vargs_)
981 {
982 init_args(std::forward<Args>(args)...);
983
984 // Setup the communication channels of the Popen class
986
988 }
989
990 int retcode() const noexcept { return retcode_; }
991
992 int wait() noexcept(false);
993
994 void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); }
995
996 void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); }
997
998 int send(const char* msg, size_t length)
999 { return stream_.send(msg, length); }
1000
1001 int send(const std::string& msg)
1002 { return send(msg.c_str(), msg.size()); }
1003
1004 int send(const std::vector<char>& msg)
1005 { return stream_.send(msg); }
1006
1007 std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length)
1008 {
1009 auto res = stream_.communicate(msg, length);
1010 retcode_ = wait();
1011 return res;
1012 }
1013
1014 std::pair<OutBuffer, ErrBuffer> communicate(const std::string& msg)
1015 {
1016 return communicate(msg.c_str(), msg.size());
1017 }
1018
1019 std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg)
1020 {
1021 auto res = stream_.communicate(msg);
1022 retcode_ = wait();
1023 return res;
1024 }
1025
1026 std::pair<OutBuffer, ErrBuffer> communicate()
1027 {
1028 return communicate(nullptr, 0);
1029 }
1030
1031private:
1032 template <typename F, typename... Args>
1033 void init_args(F&& farg, Args&&... args);
1034 void init_args();
1035 void populate_c_argv();
1036 void execute_process() noexcept(false);
1037
1038private:
1039 detail::Streams stream_;
1040
1041#ifdef __USING_WINDOWS__
1042 HANDLE process_handle_;
1043 std::future<void> cleanup_future_;
1044#endif
1045
1046 bool close_fds_ = false;
1047
1048 std::string exe_name_;
1049
1050 // Command in string format
1051 std::string args_;
1052 // Command provided as sequence
1053 std::vector<std::string> vargs_;
1054 std::vector<char*> cargv_;
1055
1056 // Pid of the child process
1057 int child_pid_ = -1;
1058
1059 int retcode_ = -1;
1060};
1061
1062inline void Popen::init_args() {
1064}
1065
1066template <typename F, typename... Args>
1067inline void Popen::init_args(F&& farg, Args&&... args)
1068{
1069 detail::ArgumentDeducer argd(this);
1070 argd.set_option(std::forward<F>(farg));
1071 init_args(std::forward<Args>(args)...);
1072}
1073
1075{
1076 cargv_.clear();
1077 cargv_.reserve(vargs_.size() + 1);
1078 for (auto& arg : vargs_) cargv_.push_back(&arg[0]);
1079 cargv_.push_back(nullptr);
1080}
1081
1082inline int Popen::wait() noexcept(false)
1083{
1084#ifdef __USING_WINDOWS__
1085 int ret = WaitForSingleObject(process_handle_, INFINITE);
1086
1087 // WaitForSingleObject with INFINITE should only return when process has signaled
1088 if (ret != WAIT_OBJECT_0) {
1089 throw OSError("Unexpected return code from WaitForSingleObject", 0);
1090 }
1091
1092 DWORD dretcode_;
1093
1094 if (FALSE == GetExitCodeProcess(process_handle_, &dretcode_))
1095 throw OSError("Failed during call to GetExitCodeProcess", 0);
1096
1097 CloseHandle(process_handle_);
1098
1099 return (int)dretcode_;
1100#else
1101 int ret, status;
1102 std::tie(ret, status) = util::wait_for_child_exit(child_pid_);
1103 if (ret == -1) {
1104 if (errno != ECHILD) throw OSError("waitpid failed", errno);
1105 return 0;
1106 }
1107 if (WIFEXITED(status)) return WEXITSTATUS(status);
1108 if (WIFSIGNALED(status)) return WTERMSIG(status);
1109 else return 255;
1110
1111 return 0;
1112#endif
1113}
1114
1115inline void Popen::execute_process() noexcept(false)
1116{
1117#ifdef __USING_WINDOWS__
1118 if (exe_name_.length()) {
1119 this->vargs_.insert(this->vargs_.begin(), this->exe_name_);
1120 this->populate_c_argv();
1121 }
1122 this->exe_name_ = vargs_[0];
1123
1124 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
1125 std::wstring argument;
1126 std::wstring command_line;
1127 bool first_arg = true;
1128
1129 for (auto arg : this->vargs_) {
1130 if (!first_arg) {
1131 command_line += L" ";
1132 } else {
1133 first_arg = false;
1134 }
1135 argument = converter.from_bytes(arg);
1136 util::quote_argument(argument, command_line, false);
1137 }
1138
1139 // CreateProcessW can modify szCmdLine so we allocate needed memory
1140 wchar_t *szCmdline = new wchar_t[command_line.size() + 1];
1141 wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
1142 PROCESS_INFORMATION piProcInfo;
1143 STARTUPINFOW siStartInfo;
1144 BOOL bSuccess = FALSE;
1145 DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
1146
1147 // Set up members of the PROCESS_INFORMATION structure.
1148 ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
1149
1150 // Set up members of the STARTUPINFOW structure.
1151 // This structure specifies the STDIN and STDOUT handles for redirection.
1152
1153 ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW));
1154 siStartInfo.cb = sizeof(STARTUPINFOW);
1155
1156 siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
1157 siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
1158 siStartInfo.hStdInput = this->stream_.g_hChildStd_IN_Rd;
1159
1160 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
1161
1162 // Create the child process.
1163 bSuccess = CreateProcessW(NULL,
1164 szCmdline, // command line
1165 NULL, // process security attributes
1166 NULL, // primary thread security attributes
1167 TRUE, // handles are inherited
1168 creation_flags, // creation flags
1169 NULL, // use parent's environment
1170 NULL, // use parent's current directory
1171 &siStartInfo, // STARTUPINFOW pointer
1172 &piProcInfo); // receives PROCESS_INFORMATION
1173
1174 // If an error occurs, exit the application.
1175 if (!bSuccess) {
1176 DWORD errorMessageID = ::GetLastError();
1177 throw CalledProcessError("CreateProcess failed: " + util::get_last_error(errorMessageID), errorMessageID);
1178 }
1179
1180 CloseHandle(piProcInfo.hThread);
1181
1182 /*
1183 TODO: use common apis to close linux handles
1184 */
1185
1186 this->process_handle_ = piProcInfo.hProcess;
1187
1188 this->cleanup_future_ = std::async(std::launch::async, [this] {
1189 WaitForSingleObject(this->process_handle_, INFINITE);
1190
1191 CloseHandle(this->stream_.g_hChildStd_ERR_Wr);
1192 CloseHandle(this->stream_.g_hChildStd_OUT_Wr);
1193 CloseHandle(this->stream_.g_hChildStd_IN_Rd);
1194 });
1195
1196/*
1197 NOTE: In the linux version, there is a check to make sure that the process
1198 has been started. Here, we do nothing because CreateProcess will throw
1199 if we fail to create the process.
1200*/
1201
1202
1203#else
1204
1205 int err_rd_pipe, err_wr_pipe;
1206 std::tie(err_rd_pipe, err_wr_pipe) = util::pipe_cloexec();
1207
1208 if (exe_name_.length()) {
1209 vargs_.insert(vargs_.begin(), exe_name_);
1211 }
1212 exe_name_ = vargs_[0];
1213
1214 child_pid_ = fork();
1215
1216 if (child_pid_ < 0) {
1217 subprocess_close(err_rd_pipe);
1218 subprocess_close(err_wr_pipe);
1219 throw OSError("fork failed", errno);
1220 }
1221
1222 if (child_pid_ == 0)
1223 {
1224 // Close descriptors belonging to parent
1226
1227 //Close the read end of the error pipe
1228 subprocess_close(err_rd_pipe);
1229
1230 detail::Child chld(this, err_wr_pipe);
1231 chld.execute_child();
1232 }
1233 else
1234 {
1235 subprocess_close(err_wr_pipe);// close child side of pipe, else get stuck in read below
1236
1238
1239 try {
1240 char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1241
1242 FILE* err_fp = fdopen(err_rd_pipe, "r");
1243 if (!err_fp) {
1244 subprocess_close(err_rd_pipe);
1245 throw OSError("fdopen failed", errno);
1246 }
1247 int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
1248 fclose(err_fp);
1249
1250 if (read_bytes || strlen(err_buf)) {
1251 // Call waitpid to reap the child process
1252 // waitpid suspends the calling process until the
1253 // child terminates.
1254 int retcode = wait();
1255
1256 // Throw whatever information we have about child failure
1257 throw CalledProcessError(err_buf, retcode);
1258 }
1259 } catch (std::exception& exp) {
1261 throw;
1262 }
1263
1264 }
1265#endif
1266}
1267
1268namespace detail {
1269
1271 popen_->exe_name_ = std::move(exe.arg_value);
1272 }
1273
1275 if (inp.rd_ch_ != -1) popen_->stream_.read_from_parent_ = inp.rd_ch_;
1276 if (inp.wr_ch_ != -1) popen_->stream_.write_to_child_ = inp.wr_ch_;
1277 }
1278
1280 if (out.wr_ch_ != -1) popen_->stream_.write_to_parent_ = out.wr_ch_;
1281 if (out.rd_ch_ != -1) popen_->stream_.read_from_child_ = out.rd_ch_;
1282 }
1283
1285 if (err.deferred_) {
1288 } else {
1289 throw std::runtime_error("Set output before redirecting error to output");
1290 }
1291 }
1292 if (err.wr_ch_ != -1) popen_->stream_.err_write_ = err.wr_ch_;
1293 if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1294 }
1295
1297 popen_->close_fds_ = cfds.close_all;
1298 }
1299
1300
1301 inline void Child::execute_child() {
1302#ifndef __USING_WINDOWS__
1303 int sys_ret = -1;
1304 auto& stream = parent_->stream_;
1305
1306 try {
1307 if (stream.write_to_parent_ == 0)
1308 stream.write_to_parent_ = dup(stream.write_to_parent_);
1309
1310 if (stream.err_write_ == 0 || stream.err_write_ == 1)
1311 stream.err_write_ = dup(stream.err_write_);
1312
1313 // Make the child owned descriptors as the
1314 // stdin, stdout and stderr for the child process
1315 auto _dup2_ = [](int fd, int to_fd) {
1316 if (fd == to_fd) {
1317 // dup2 syscall does not reset the
1318 // CLOEXEC flag if the descriptors
1319 // provided to it are same.
1320 // But, we need to reset the CLOEXEC
1321 // flag as the provided descriptors
1322 // are now going to be the standard
1323 // input, output and error
1324 util::set_clo_on_exec(fd, false);
1325 } else if(fd != -1) {
1326 int res = dup2(fd, to_fd);
1327 if (res == -1) throw OSError("dup2 failed", errno);
1328 }
1329 };
1330
1331 // Create the standard streams
1332 _dup2_(stream.read_from_parent_, 0); // Input stream
1333 _dup2_(stream.write_to_parent_, 1); // Output stream
1334 _dup2_(stream.err_write_, 2); // Error stream
1335
1336 // Close the duped descriptors
1337 if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1338 subprocess_close(stream.read_from_parent_);
1339
1340 if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1341 subprocess_close(stream.write_to_parent_);
1342
1343 if (stream.err_write_ != -1 && stream.err_write_ > 2)
1344 subprocess_close(stream.err_write_);
1345
1346 // Close all the inherited fd's except the error write pipe
1347 if (parent_->close_fds_) {
1348 // If possible, try to get the list of open file descriptors from the
1349 // operating system. This is more efficient, but not guaranteed to be
1350 // available.
1351#ifdef __linux__
1352 // For Linux, enumerate /proc/<pid>/fd.
1353 try {
1354 std::vector<int> fds_to_close;
1355 for (const auto& it : fs::directory_iterator(strprintf("/proc/%d/fd", getpid()))) {
1356 auto fd{ToIntegral<uint64_t>(it.path().filename().native())};
1357 if (!fd || *fd > std::numeric_limits<int>::max()) continue;
1358 if (*fd <= 2) continue; // leave std{in,out,err} alone
1359 if (*fd == static_cast<uint64_t>(err_wr_pipe_)) continue;
1360 fds_to_close.push_back(*fd);
1361 }
1362 for (const int fd : fds_to_close) {
1363 close(fd);
1364 }
1365 } catch (const fs::filesystem_error &e) {
1366 throw OSError("/proc/<pid>/fd iteration failed", e.code().value());
1367 }
1368#else
1369 // On other operating systems, iterate over all file descriptor slots
1370 // and try to close them all.
1371 int max_fd = sysconf(_SC_OPEN_MAX);
1372 if (max_fd == -1) throw OSError("sysconf failed", errno);
1373
1374 for (int i = 3; i < max_fd; i++) {
1375 if (i == err_wr_pipe_) continue;
1376 close(i);
1377 }
1378#endif
1379 }
1380
1381 // Replace the current image with the executable
1382 sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1383
1384 if (sys_ret == -1) throw OSError("execve failed", errno);
1385
1386 } catch (const OSError& exp) {
1387 // Just write the exception message
1388 // TODO: Give back stack trace ?
1389 std::string err_msg(exp.what());
1390 //ATTN: Can we do something on error here ?
1391 util::write_n(err_wr_pipe_, err_msg.c_str(), err_msg.length());
1392 }
1393
1394 // Calling application would not get this
1395 // exit failure
1396 _exit (EXIT_FAILURE);
1397#endif
1398 }
1399
1400
1402 {
1403#ifdef __USING_WINDOWS__
1404 util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1405 this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1406 this->write_to_child_ = subprocess_fileno(this->input());
1407
1408 util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1409 this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1410 this->read_from_child_ = subprocess_fileno(this->output());
1411
1412 util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1413 this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1414 this->err_read_ = subprocess_fileno(this->error());
1415#else
1416
1417 if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
1418 if (read_from_child_ != -1) output(fdopen(read_from_child_, "rb"));
1419 if (err_read_ != -1) error(fdopen(err_read_, "rb"));
1420
1421 auto handles = {input(), output(), error()};
1422
1423 for (auto& h : handles) {
1424 if (h == nullptr) continue;
1425 setvbuf(h, nullptr, _IONBF, BUFSIZ);
1426 }
1427 #endif
1428 }
1429
1430 inline int Communication::send(const char* msg, size_t length)
1431 {
1432 if (stream_->input() == nullptr) return -1;
1433 return std::fwrite(msg, sizeof(char), length, stream_->input());
1434 }
1435
1436 inline int Communication::send(const std::vector<char>& msg)
1437 {
1438 return send(msg.data(), msg.size());
1439 }
1440
1441 inline std::pair<OutBuffer, ErrBuffer>
1442 Communication::communicate(const char* msg, size_t length)
1443 {
1444 // Optimization from subprocess.py
1445 // If we are using one pipe, or no pipe
1446 // at all, using select() or threads is unnecessary.
1447 auto hndls = {stream_->input(), stream_->output(), stream_->error()};
1448 int count = std::count(std::begin(hndls), std::end(hndls), nullptr);
1449 const int len_conv = length;
1450
1451 if (count >= 2) {
1452 OutBuffer obuf;
1453 ErrBuffer ebuf;
1454 if (stream_->input()) {
1455 if (msg) {
1456 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1457 if (wbytes < len_conv) {
1458 if (errno != EPIPE && errno != EINVAL) {
1459 throw OSError("fwrite error", errno);
1460 }
1461 }
1462 }
1463 // Close the input stream
1464 stream_->input_.reset();
1465 } else if (stream_->output()) {
1466 // Read till EOF
1467 // ATTN: This could be blocking, if the process
1468 // at the other end screws up, we get screwed as well
1469 obuf.add_cap(out_buf_cap_);
1470
1471 int rbytes = util::read_all(
1472 stream_->output(),
1473 obuf.buf);
1474
1475 if (rbytes == -1) {
1476 throw OSError("read to obuf failed", errno);
1477 }
1478
1479 obuf.length = rbytes;
1480 // Close the output stream
1481 stream_->output_.reset();
1482
1483 } else if (stream_->error()) {
1484 // Same screwness applies here as well
1485 ebuf.add_cap(err_buf_cap_);
1486
1487 int rbytes = util::read_atmost_n(
1488 stream_->error(),
1489 ebuf.buf.data(),
1490 ebuf.buf.size());
1491
1492 if (rbytes == -1) {
1493 throw OSError("read to ebuf failed", errno);
1494 }
1495
1496 ebuf.length = rbytes;
1497 // Close the error stream
1498 stream_->error_.reset();
1499 }
1500 return std::make_pair(std::move(obuf), std::move(ebuf));
1501 }
1502
1503 return communicate_threaded(msg, length);
1504 }
1505
1506
1507 inline std::pair<OutBuffer, ErrBuffer>
1508 Communication::communicate_threaded(const char* msg, size_t length)
1509 {
1510 OutBuffer obuf;
1511 ErrBuffer ebuf;
1512 std::future<int> out_fut, err_fut;
1513 const int length_conv = length;
1514
1515 if (stream_->output()) {
1516 obuf.add_cap(out_buf_cap_);
1517
1518 out_fut = std::async(std::launch::async,
1519 [&obuf, this] {
1520 return util::read_all(this->stream_->output(), obuf.buf);
1521 });
1522 }
1523 if (stream_->error()) {
1524 ebuf.add_cap(err_buf_cap_);
1525
1526 err_fut = std::async(std::launch::async,
1527 [&ebuf, this] {
1528 return util::read_all(this->stream_->error(), ebuf.buf);
1529 });
1530 }
1531 if (stream_->input()) {
1532 if (msg) {
1533 int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input());
1534 if (wbytes < length_conv) {
1535 if (errno != EPIPE && errno != EINVAL) {
1536 throw OSError("fwrite error", errno);
1537 }
1538 }
1539 }
1540 stream_->input_.reset();
1541 }
1542
1543 if (out_fut.valid()) {
1544 int res = out_fut.get();
1545 if (res != -1) obuf.length = res;
1546 else obuf.length = 0;
1547 }
1548 if (err_fut.valid()) {
1549 int res = err_fut.get();
1550 if (res != -1) ebuf.length = res;
1551 else ebuf.length = 0;
1552 }
1553
1554 return std::make_pair(std::move(obuf), std::move(ebuf));
1555 }
1556
1557} // end namespace detail
1558
1559}
1560
1561#endif // BITCOIN_UTIL_SUBPROCESS_H
int ret
int flags
Definition: bitcoin-tx.cpp:529
ArgsManager & args
Definition: bitcoind.cpp:277
Buffer(size_t cap)
Definition: subprocess.h:714
void add_cap(size_t cap)
Definition: subprocess.h:715
std::vector< char > buf
Definition: subprocess.h:718
CalledProcessError(const std::string &error_msg, int retcode)
Definition: subprocess.h:149
OSError(const std::string &err_msg, int err_code)
Definition: subprocess.h:168
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:1007
void populate_c_argv()
Definition: subprocess.h:1074
detail::Streams stream_
Definition: subprocess.h:1039
std::pair< OutBuffer, ErrBuffer > communicate(const std::string &msg)
Definition: subprocess.h:1014
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:994
Popen(std::initializer_list< const char * > cmd_args, Args &&...args)
Definition: subprocess.h:968
std::vector< char * > cargv_
Definition: subprocess.h:1054
Popen(std::vector< std::string > vargs_, Args &&... args)
Definition: subprocess.h:980
void execute_process() noexcept(false)
Definition: subprocess.h:1115
std::vector< std::string > vargs_
Definition: subprocess.h:1053
std::string exe_name_
Definition: subprocess.h:1048
int send(const std::vector< char > &msg)
Definition: subprocess.h:1004
int send(const std::string &msg)
Definition: subprocess.h:1001
std::pair< OutBuffer, ErrBuffer > communicate()
Definition: subprocess.h:1026
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:1019
int retcode() const noexcept
Definition: subprocess.h:990
Popen(const std::string &cmd_args, Args &&...args)
Definition: subprocess.h:955
int wait() noexcept(false)
Definition: subprocess.h:1082
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:996
int send(const char *msg, size_t length)
Definition: subprocess.h:998
std::string args_
Definition: subprocess.h:1051
Child(Popen *p, int err_wr_pipe)
Definition: subprocess.h:766
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:807
Communication(Communication &&)=default
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:806
int send(const char *msg, size_t length)
Definition: subprocess.h:1430
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:1442
std::pair< OutBuffer, ErrBuffer > communicate_threaded(const char *msg, size_t length)
Definition: subprocess.h:1508
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:803
std::pair< OutBuffer, ErrBuffer > communicate(const std::vector< char > &msg)
Definition: subprocess.h:890
int send(const std::vector< char > &msg)
Definition: subprocess.h:884
void set_out_buf_cap(size_t cap)
Definition: subprocess.h:877
Streams(Streams &&)=default
std::pair< OutBuffer, ErrBuffer > communicate(const char *msg, size_t length)
Definition: subprocess.h:887
void set_err_buf_cap(size_t cap)
Definition: subprocess.h:878
std::shared_ptr< FILE > output_
Definition: subprocess.h:897
std::shared_ptr< FILE > error_
Definition: subprocess.h:898
Streams & operator=(const Streams &)=delete
int send(const char *msg, size_t length)
Definition: subprocess.h:881
Streams(const Streams &)=delete
Streams & operator=(Streams &&)=default
std::shared_ptr< FILE > input_
Definition: subprocess.h:896
#define T(expected, seed, data)
static int read_all(FILE *fp, std::vector< char > &buf)
Definition: subprocess.h:468
static int read_atmost_n(FILE *fp, char *buf, size_t read_upto)
Definition: subprocess.h:427
static void set_clo_on_exec(int fd, bool set=true)
Definition: subprocess.h:348
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.h:317
static std::pair< int, int > wait_for_child_exit(int pid)
Definition: subprocess.h:517
static std::pair< int, int > pipe_cloexec() noexcept(false)
Definition: subprocess.h:372
static int write_n(int fd, const char *buf, size_t length)
Definition: subprocess.h:400
static const size_t SP_MAX_ERR_BUF_SIZ
Definition: subprocess.h:125
static const size_t DEFAULT_BUF_CAP_BYTES
Definition: subprocess.h:130
void set_option(executable &&exe)
Definition: subprocess.h:1270
error(FILE *fp)
Definition: subprocess.h:672
error(IOTYPE typ)
Definition: subprocess.h:679
error(const char *filename)
Definition: subprocess.h:674
input(const char *filename)
Definition: subprocess.h:610
input(IOTYPE typ)
Definition: subprocess.h:615
input(FILE *fp)
Definition: subprocess.h:608
output(IOTYPE typ)
Definition: subprocess.h:648
output(const char *filename)
Definition: subprocess.h:643
output(FILE *fp)
Definition: subprocess.h:641
std::string arg_value
Definition: subprocess.h:563
string_arg(const char *arg)
Definition: subprocess.h:560
string_arg(std::string &&arg)
Definition: subprocess.h:561
string_arg(const std::string &arg)
Definition: subprocess.h:562
#define subprocess_close
Definition: subprocess.h:92
#define subprocess_write
Definition: subprocess.h:95
#define subprocess_fileno
Definition: subprocess.h:93
#define subprocess_open
Definition: subprocess.h:94
std::string SysErrorString(int err)
Return system error string from errno value.
Definition: syserror.cpp:19
static int count
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
assert(!tx.IsCoinBase())