Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501* pair.first : Return code of the waitpid call.502* pair.second : Exit status of the process.503*504* NOTE: This is a blocking call as in, it will loop505* till the child is exited.506*/507static inline508std::pair<int, int> wait_for_child_exit(int pid)509{510int status = 0;511int ret = -1;512while (1) {513ret = waitpid(pid, &status, 0);514if (ret == -1) break;515if (ret == 0) continue;516return std::make_pair(ret, status);517}519return std::make_pair(ret, status);520}521#endif523} // end namespace util527/* -------------------------------528* Popen Arguments529* -------------------------------530*/532/*!533* Base class for all arguments involving string value.534*/535struct string_arg536{537string_arg(const char* arg): arg_value(arg) {}538string_arg(std::string&& arg): arg_value(std::move(arg)) {}539string_arg(const std::string& arg): arg_value(arg) {}540std::string arg_value;541};543/*!544* Option to specify the executable name separately545* from the args sequence.546* In this case the cmd args must only contain the547* options required for this executable.548*549* Eg: executable{"ls"}550*/551struct executable: string_arg552{553template <typename T>554executable(T&& arg): string_arg(std::forward<T>(arg)) {}555};557/*!558* Used for redirecting input/output/error559*/560enum IOTYPE {561STDOUT = 1,562STDERR,563PIPE,564};566//TODO: A common base/interface for below stream structures ??568/*!569* Option to specify the input channel for the child570* process. It can be:571* 1. An already open file descriptor.572* 2. A file name.573* 3. IOTYPE. Usual a PIPE574*575* Eg: input{PIPE}576* OR in case of redirection, output of another Popen577* input{popen.output()}578*/579struct input580{581// For an already existing file descriptor.582explicit input(int fd): rd_ch_(fd) {}584// FILE pointer.585explicit input (FILE* fp):input(subprocess_fileno(fp)) { assert(fp); }587explicit input(const char* filename) {588int fd = subprocess_open(filename, O_RDONLY);589if (fd == -1) throw OSError("File not found: ", errno);590rd_ch_ = fd;591}592explicit input(IOTYPE typ) {593assert (typ == PIPE && "STDOUT/STDERR not allowed");594#ifndef WIN32595std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();596#endif597}599int rd_ch_ = -1;600int wr_ch_ = -1;601};604/*!605* Option to specify the output channel for the child606* process. It can be:607* 1. An already open file descriptor.608* 2. A file name.609* 3. IOTYPE. Usually a PIPE.610*611* Eg: output{PIPE}612* OR output{"output.txt"}613*/614struct output615{616explicit output(int fd): wr_ch_(fd) {}618explicit output (FILE* fp):output(subprocess_fileno(fp)) { assert(fp); }620explicit output(const char* filename) {621int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);622if (fd == -1) throw OSError("File not found: ", errno);623wr_ch_ = fd;624}625explicit output(IOTYPE typ) {626assert (typ == PIPE && "STDOUT/STDERR not allowed");627#ifndef WIN32628std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();629#endif630}632int rd_ch_ = -1;633int wr_ch_ = -1;634};637/*!638* Option to specify the error channel for the child639* process. It can be:640* 1. An already open file descriptor.641* 2. A file name.642* 3. IOTYPE. Usually a PIPE or STDOUT643*644*/645struct error646{647explicit error(int fd): wr_ch_(fd) {}649explicit error(FILE* fp):error(subprocess_fileno(fp)) { assert(fp); }651explicit error(const char* filename) {652int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);653if (fd == -1) throw OSError("File not found: ", errno);654wr_ch_ = fd;655}656explicit error(IOTYPE typ) {657assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed");658if (typ == PIPE) {659#ifndef WIN32660std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();661#endif662} else {663// Need to defer it till we have checked all arguments664deferred_ = true;665}666}668bool deferred_ = false;669int rd_ch_ = -1;670int wr_ch_ = -1;671};673// ~~~~ End Popen Args ~~~~676/*!677* class: Buffer678* This class is a very thin wrapper around std::vector<char>679* This is basically used to determine the length of the actual680* data stored inside the dynamically resized vector.681*682* This is what is returned as the output to the communicate683* function, so, users must know about this class.684*685* OutBuffer and ErrBuffer are just different typedefs to this class.686*/687class Buffer688{689public:690Buffer() = default;691explicit Buffer(size_t cap) { buf.resize(cap); }692void add_cap(size_t cap) { buf.resize(cap); }694public:695std::vector<char> buf;696size_t length = 0;697};699// Buffer for storing output written to output fd700using OutBuffer = Buffer;701// Buffer for storing output written to error fd702using ErrBuffer = Buffer;705// Fwd Decl.706class Popen;708/*---------------------------------------------------709* DETAIL NAMESPACE710*---------------------------------------------------711*/713namespace detail {714/*!715* A helper class to Popen class for setting716* options as provided in the Popen constructor.717* This design allows us to _not_ have any fixed position718* to any arguments and specify them in a way similar to what719* can be done in python.720*/721struct ArgumentDeducer722{723ArgumentDeducer(Popen* p): popen_(p) {}725void set_option(executable&& exe);726void set_option(input&& inp);727void set_option(output&& out);728void set_option(error&& err);730private:731Popen* popen_ = nullptr;732};734#ifndef WIN32735/*!736* A helper class to Popen.737* This takes care of all the fork-exec logic738* in the execute_child API.739*/740class Child741{742public:743Child(Popen* p, int err_wr_pipe):744parent_(p),745err_wr_pipe_(err_wr_pipe)746{}748void execute_child();750private:
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.