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.
1// Based on the https://github.com/arun11299/cpp-subprocess project.3/*!5Documentation for C++ subprocessing library.7@copyright The code is licensed under the [MIT8License](http://opensource.org/licenses/MIT):9<br>10Copyright © 2016-2018 Arun Muralidharan.11<br>12Permission is hereby granted, free of charge, to any person obtaining a copy13of this software and associated documentation files (the "Software"), to deal14in the Software without restriction, including without limitation the rights15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell16copies of the Software, and to permit persons to whom the Software is17furnished to do so, subject to the following conditions:18<br>19The above copyright notice and this permission notice shall be included in20all copies or substantial portions of the Software.21<br>22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE28SOFTWARE.30@author [Arun Muralidharan]31@see https://github.com/arun11299/cpp-subprocess to download the source code33@version 1.0.034*/36#ifndef BITCOIN_UTIL_SUBPROCESS_H37#define BITCOIN_UTIL_SUBPROCESS_H39#include <util/check.h>40#include <util/syserror.h>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>57extern "C" {58#ifdef WIN3259#include <windows.h>60#include <io.h>61#else62#include <sys/wait.h>63#include <unistd.h>64#endif65#include <csignal>66#include <fcntl.h>67#include <sys/types.h>68}70// The Microsoft C++ compiler issues deprecation warnings71// 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 _close76#define subprocess_fileno _fileno77#define subprocess_open _open78#define subprocess_write _write79#else80#define subprocess_close close81#define subprocess_fileno fileno82#define subprocess_open open83#define subprocess_write write84#endif86/*!87* Getting started with reading this source code.88* The source is mainly divided into four parts:89* 1. Exception Classes:90* These are very basic exception classes derived from91* runtime_error exception.92* There are two types of exception thrown from subprocess93* library: OSError and CalledProcessError94*95* 2. Popen Class96* This is the main class the users will deal with. It97* provides with all the API's to deal with processes.98*99* 3. Util namespace100* It includes some helper functions to split/join a string,101* reading from file descriptors, waiting on a process, fcntl102* options on file descriptors etc.103*104* 4. Detail namespace105* This includes some metaprogramming and helper classes.106*/109namespace subprocess {111// Max buffer size allocated on stack for read error112// from pipe113inline constexpr size_t SP_MAX_ERR_BUF_SIZ = 1024;115// Default buffer capacity for OutBuffer and ErrBuffer.116// If the data exceeds this capacity, the buffer size is grown117// by 1.5 times its previous capacity118inline constexpr size_t DEFAULT_BUF_CAP_BYTES = 8192;121/*-----------------------------------------------122* EXCEPTION CLASSES123*-----------------------------------------------124*/126/*!127* class: CalledProcessError128* Thrown when there was error executing the command.129* Check Popen class API's to know when this exception130* can be thrown.131*132*/133class CalledProcessError: public std::runtime_error134{135public:136int retcode;137CalledProcessError(const std::string& error_msg, int retcode):138std::runtime_error(error_msg), retcode(retcode)139{}140};143/*!144* class: OSError145* Thrown when some system call fails to execute or give result.146* The exception message contains the name of the failed system call147* with the stringisized errno code.148* Check Popen class API's to know when this exception would be149* thrown.150* Its usual that the API exception specification would have151* this exception together with CalledProcessError.152*/153class OSError: public std::runtime_error154{155public:156OSError(const std::string& err_msg, int err_code):157std::runtime_error(err_msg + ": " + SysErrorString(err_code))158{}159};161//--------------------------------------------------------------------162namespace util163{164#ifdef WIN32165inline void quote_argument(const std::string &argument, std::string &command_line,166bool force)167{168constexpr char quote = '"';169constexpr char backslash = '\\';171//172// Unless we're told otherwise, don't quote unless we actually173// need to do so --- hopefully avoid problems if programs won't174// parse quotes properly175//177if (force == false && argument.empty() == false &&178argument.find_first_of(" \t\n\v") == argument.npos) {179command_line.append(argument);180}181else {182command_line.push_back(quote);184for (auto it = argument.begin();; ++it) {185unsigned number_backslashes = 0;187while (it != argument.end() && *it == backslash) {188++it;189++number_backslashes;190}192if (it == argument.end()) {194//195// Escape all backslashes, but let the terminating196// double quotation mark we add below be interpreted197// as a metacharacter.198//200command_line.append(number_backslashes * 2, backslash);201break;202}203else if (*it == quote) {205//206// Escape all backslashes and the following207// double quotation mark.208//210command_line.append(number_backslashes * 2 + 1, backslash);211command_line.push_back(*it);212}213else {215//216// Backslashes aren't special here.217//219command_line.append(number_backslashes, backslash);220command_line.push_back(*it);221}222}224command_line.push_back(quote);225}226}228inline std::string get_last_error(DWORD errorMessageID)229{230if (errorMessageID == 0)231return std::string();233LPSTR messageBuffer = nullptr;234size_t size = FormatMessageA(235FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |236FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,237NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),238(LPSTR)&messageBuffer, 0, NULL);240std::string message(messageBuffer, size);242LocalFree(messageBuffer);244return message;245}247inline FILE *file_from_handle(HANDLE h, const char *mode)248{249int md;250if (!mode) {
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.