process.cpp
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 <ipc/process.h> 6 #include <ipc/protocol.h> 7 #include <mp/util.h> 8 #include <tinyformat.h> 9 #include <util/fs.h> 10 #include <util/strencodings.h> 11 12 #include <cstdint> 13 #include <cstdlib> 14 #include <exception> 15 #include <iostream> 16 #include <stdexcept> 17 #include <string.h> 18 #include <system_error> 19 #include <unistd.h> 20 #include <utility> 21 #include <vector> 22 23 namespace ipc { 24 namespace { 25 class ProcessImpl : public Process 26 { 27 public: 28 int spawn(const std::string& new_exe_name, const fs::path& argv0_path, int& pid) override 29 { 30 return mp::SpawnProcess(pid, [&](int fd) { 31 fs::path path = argv0_path; 32 path.remove_filename(); 33 path /= fs::PathFromString(new_exe_name); 34 return std::vector<std::string>{fs::PathToString(path), "-ipcfd", strprintf("%i", fd)}; 35 }); 36 } 37 int waitSpawned(int pid) override { return mp::WaitProcess(pid); } 38 bool checkSpawned(int argc, char* argv[], int& fd) override 39 { 40 // If this process was not started with a single -ipcfd argument, it is 41 // not a process spawned by the spawn() call above, so return false and 42 // do not try to serve requests. 43 if (argc != 3 || strcmp(argv[1], "-ipcfd") != 0) { 44 return false; 45 } 46 // If a single -ipcfd argument was provided, return true and get the 47 // file descriptor so Protocol::serve() can be called to handle 48 // requests from the parent process. The -ipcfd argument is not valid 49 // in combination with other arguments because the parent process 50 // should be able to control the child process through the IPC protocol 51 // without passing information out of band. 52 if (!ParseInt32(argv[2], &fd)) { 53 throw std::runtime_error(strprintf("Invalid -ipcfd number '%s'", argv[2])); 54 } 55 return true; 56 } 57 }; 58 } // namespace 59 60 std::unique_ptr<Process> MakeProcess() { return std::make_unique<ProcessImpl>(); } 61 } // namespace ipc