30 #include <arpa/inet.h>
34 #include <sys/socket.h>
36 #include <sys/types.h>
44 #if defined(__cpp_lib_filesystem) || __has_include(<filesystem>)
53 #include <experimental/filesystem>
55 namespace filesystem = experimental::filesystem;
72 buildListenSocket(
const std::string &path,
const std::string &
name)
78 std::filesystem::path
p(path);
88 listener(buildListenSocket(params.server_path,
name()))
90 fatal_if(
system ==
nullptr,
"Requires a system to share memory from!");
116 char* char_buffer =
reinterpret_cast<char*
>(buffer);
118 ssize_t retv = recv(pfd.fd, char_buffer +
offset, size -
offset, 0);
121 }
else if (errno != EINTR) {
122 warn(
"%s: recv failed: %s",
name(), strerror(errno));
132 int cli_fd = shmServer->listener->accept();
133 inform(
"%s: accept new connection %d",
name(), cli_fd);
134 shmServer->clientSocketEvents[cli_fd].reset(
144 if (revents & (POLLHUP | POLLERR | POLLNVAL)) {
156 if (!tryReadAll(&req_type,
sizeof(req_type))) {
160 warn(
"%s: receive unknown request: %d",
name(),
161 static_cast<int>(req_type));
164 if (!tryReadAll(&request,
sizeof(request))) {
167 AddrRange range(request.start, request.end);
171 const auto& stores = shmServer->system->getPhysMem().getBackingStore();
172 auto it = std::find_if(
174 return entry.shmFd >= 0 && range.isSubset(entry.range);
176 if (it == stores.end()) {
177 warn(
"%s: cannot find backing store for %s",
name(),
181 inform(
"%s: find shared backing store for %s at %s, shm=%d:%lld",
183 (
unsigned long long)it->shmOffset);
197 response.offset = it->shmOffset + (range.
start() - it->range.start());
198 iovec ios = {.iov_base = &response, .iov_len =
sizeof(response)};
204 char buf[CMSG_SPACE(
sizeof(it->shmFd))];
205 struct cmsghdr
align;
207 msg.msg_control = cmsgs.buf;
208 msg.msg_controllen =
sizeof(cmsgs.buf);
209 cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
210 cmsg->cmsg_level = SOL_SOCKET;
211 cmsg->cmsg_type = SCM_RIGHTS;
212 cmsg->cmsg_len = CMSG_LEN(
sizeof(it->shmFd));
213 memcpy(CMSG_DATA(cmsg), &it->shmFd,
sizeof(it->shmFd));
215 int retv = sendmsg(pfd.fd, &msg, 0);
217 warn(
"%s: sendmsg failed: %s",
name(), strerror(errno));
220 if (retv !=
sizeof(response)) {
221 warn(
"%s: failed to send all response at once",
name());
234 shmServer->clientSocketEvents.erase(pfd.fd);