Bitcoin Core 28.99.0
P2P Digital Currency
interfaces.cpp
Go to the documentation of this file.
1// Copyright (c) 2021-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <common/args.h>
6#include <common/system.h>
7#include <interfaces/init.h>
8#include <interfaces/ipc.h>
10#include <ipc/process.h>
11#include <ipc/protocol.h>
12#include <logging.h>
13#include <tinyformat.h>
14#include <util/fs.h>
15
16#include <cstdio>
17#include <cstdlib>
18#include <functional>
19#include <memory>
20#include <stdexcept>
21#include <string.h>
22#include <string>
23#include <unistd.h>
24#include <utility>
25#include <vector>
26
27namespace ipc {
28namespace {
29class IpcImpl : public interfaces::Ipc
30{
31public:
32 IpcImpl(const char* exe_name, const char* process_argv0, interfaces::Init& init)
33 : m_exe_name(exe_name), m_process_argv0(process_argv0), m_init(init),
34 m_protocol(ipc::capnp::MakeCapnpProtocol()), m_process(ipc::MakeProcess())
35 {
36 }
37 std::unique_ptr<interfaces::Init> spawnProcess(const char* new_exe_name) override
38 {
39 int pid;
40 int fd = m_process->spawn(new_exe_name, m_process_argv0, pid);
41 LogDebug(::BCLog::IPC, "Process %s pid %i launched\n", new_exe_name, pid);
42 auto init = m_protocol->connect(fd, m_exe_name);
43 Ipc::addCleanup(*init, [this, new_exe_name, pid] {
44 int status = m_process->waitSpawned(pid);
45 LogDebug(::BCLog::IPC, "Process %s pid %i exited with status %i\n", new_exe_name, pid, status);
46 });
47 return init;
48 }
49 bool startSpawnedProcess(int argc, char* argv[], int& exit_status) override
50 {
51 exit_status = EXIT_FAILURE;
52 int32_t fd = -1;
53 if (!m_process->checkSpawned(argc, argv, fd)) {
54 return false;
55 }
56 m_protocol->serve(fd, m_exe_name, m_init);
58 return true;
59 }
60 std::unique_ptr<interfaces::Init> connectAddress(std::string& address) override
61 {
62 if (address.empty() || address == "0") return nullptr;
63 int fd;
64 if (address == "auto") {
65 // Treat "auto" the same as "unix" except don't treat it an as error
66 // if the connection is not accepted. Just return null so the caller
67 // can work offline without a connection, or spawn a new
68 // bitcoin-node process and connect to it.
69 address = "unix";
70 try {
71 fd = m_process->connect(gArgs.GetDataDirNet(), "bitcoin-node", address);
72 } catch (const std::system_error& e) {
73 // If connection type is auto and socket path isn't accepting connections, or doesn't exist, catch the error and return null;
74 if (e.code() == std::errc::connection_refused || e.code() == std::errc::no_such_file_or_directory) {
75 return nullptr;
76 }
77 throw;
78 }
79 } else {
80 fd = m_process->connect(gArgs.GetDataDirNet(), "bitcoin-node", address);
81 }
82 return m_protocol->connect(fd, m_exe_name);
83 }
84 void listenAddress(std::string& address) override
85 {
86 int fd = m_process->bind(gArgs.GetDataDirNet(), m_exe_name, address);
87 m_protocol->listen(fd, m_exe_name, m_init);
88 }
89 void addCleanup(std::type_index type, void* iface, std::function<void()> cleanup) override
90 {
91 m_protocol->addCleanup(type, iface, std::move(cleanup));
92 }
93 Context& context() override { return m_protocol->context(); }
94 const char* m_exe_name;
95 const char* m_process_argv0;
96 interfaces::Init& m_init;
97 std::unique_ptr<Protocol> m_protocol;
98 std::unique_ptr<Process> m_process;
99};
100} // namespace
101} // namespace ipc
102
103namespace interfaces {
104std::unique_ptr<Ipc> MakeIpc(const char* exe_name, const char* process_argv0, Init& init)
105{
106 return std::make_unique<ipc::IpcImpl>(exe_name, process_argv0, init);
107}
108} // namespace interfaces
ArgsManager gArgs
Definition: args.cpp:42
int exit_status
return EXIT_SUCCESS
std::unique_ptr< interfaces::Init > init
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:234
Initial interface created when a process is first started, and used to give and get access to other i...
Definition: init.h:31
Interface providing access to interprocess-communication (IPC) functionality.
Definition: ipc.h:50
#define LogDebug(category,...)
Definition: logging.h:280
std::unique_ptr< Ipc > MakeIpc(const char *exe_name, const char *process_argv0, Init &init)
Return implementation of Ipc interface.
Definition: interfaces.cpp:104
std::unique_ptr< Protocol > MakeCapnpProtocol()
Definition: protocol.cpp:102
Definition: ipc.h:12
std::unique_ptr< Process > MakeProcess()
Constructor for Process interface.
Definition: process.cpp:154