21#include <sys/socket.h>
31class ProcessImpl :
public Process
38 path.remove_filename();
44 bool checkSpawned(
int argc,
char*
argv[],
int& fd)
override
60 throw std::runtime_error(
strprintf(
"Invalid -ipcfd number '%s'",
argv[2]));
65 int connect(
const fs::path&
data_dir,
67 std::string& address)
override;
68 int bind(
const fs::path&
data_dir,
const std::string&
exe_name, std::string& address)
override;
77 if (address ==
"unix" || address.starts_with(
"unix:")) {
79 if (address.size() <= 5) {
86 if (
path_str.size() >=
sizeof(addr.sun_path)) {
87 error =
strprintf(
"Unix address path %s exceeded maximum socket path length", fs::quoted(fs::PathToString(path)));
90 memset(&addr, 0,
sizeof(addr));
96 error =
strprintf(
"Unrecognized address '%s'", address);
100int ProcessImpl::connect(
const fs::path&
data_dir,
102 std::string& address)
107 throw std::invalid_argument(error);
112 throw std::system_error(
errno, std::system_category());
114 if (::connect(fd, (
struct sockaddr*)&addr,
sizeof(addr)) == 0) {
118 if (::close(fd) != 0) {
121 throw std::system_error(
connect_error, std::system_category());
124int ProcessImpl::bind(
const fs::path&
data_dir,
const std::string&
exe_name, std::string& address)
129 throw std::invalid_argument(error);
132 if (addr.sun_family ==
AF_UNIX) {
133 fs::path path = addr.sun_path;
134 if (path.has_parent_path()) fs::create_directories(path.parent_path());
135 if (fs::symlink_status(path).type() == fs::file_type::socket) {
142 throw std::system_error(
errno, std::system_category());
145 if (::bind(fd, (
struct sockaddr*)&addr,
sizeof(addr)) == 0) {
149 if (::close(fd) != 0) {
152 throw std::system_error(
bind_error, std::system_category());
156std::unique_ptr<Process>
MakeProcess() {
return std::make_unique<ProcessImpl>(); }
static std::string PathToString(const path &path)
Convert path object to a byte string.
static path PathFromString(const std::string &string)
Convert byte string to path object.
std::unique_ptr< Process > MakeProcess()
Constructor for Process interface.
int WaitProcess(int pid)
Wait for a process to exit and return its exit code.
int SpawnProcess(int &pid, FdToArgsFn &&fd_to_args)
Spawn a new process that communicates with the current process over a socket pair.
std::string_view RemovePrefixView(std::string_view str, std::string_view prefix)
std::string SysErrorString(int err)
Return system error string from errno value.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.