| 122 | } |
| 123 | |
| 124 | int ProcessImpl::bind(const fs::path& data_dir, const std::string& exe_name, std::string& address) |
| 125 | { |
| 126 | struct sockaddr_un addr; |
| 127 | std::string error; |
| 128 | if (!ParseAddress(address, data_dir, exe_name, addr, error)) { |
| 129 | throw std::invalid_argument(error); |
| 130 | } |
| 131 | |
| 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) { |
| 136 | fs::remove(path); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | int fd; |
| 141 | if ((fd = ::socket(addr.sun_family, SOCK_STREAM, 0)) == -1) { |
| 142 | throw std::system_error(errno, std::system_category()); |
| 143 | } |
| 144 | |
| 145 | if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { |
| 146 | return fd; |
| 147 | } |
| 148 | int bind_error = errno; |
| 149 | if (::close(fd) != 0) { |
| 150 | LogWarning("Error closing file descriptor %i: %s", fd, SysErrorString(errno)); |
| 151 | } |
| 152 | throw std::system_error(bind_error, std::system_category()); |
| 153 | } |
| 154 | } // namespace |
| 155 | |
| 156 | std::unique_ptr<Process> MakeProcess() { return std::make_unique<ProcessImpl>(); } |