4 #include <sys/socket.h> 14 #include <libshm/err.h> 15 #include <libshm/alloc_info.h> 23 SYSCHECK_ERR_RETURN_NEG1(socket_fd = socket(AF_UNIX, SOCK_STREAM, 0));
26 Socket(
Socket&& other) noexcept : socket_fd(other.socket_fd) { other.socket_fd = -1; };
27 explicit Socket(
int fd) : socket_fd(fd) {}
34 struct sockaddr_un prepare_address(const char *path) {
35 struct sockaddr_un address;
36 address.sun_family = AF_UNIX;
37 strcpy(address.sun_path, path);
41 size_t address_length(
struct sockaddr_un address) {
42 return strlen(address.sun_path) +
sizeof(address.sun_family);
45 void recv(
void *_buffer,
size_t num_bytes) {
46 char *buffer = (
char*)_buffer;
47 size_t bytes_received = 0;
48 ssize_t step_received;
49 struct pollfd pfd = {0};
52 while (bytes_received < num_bytes) {
53 SYSCHECK_ERR_RETURN_NEG1(poll(&pfd, 1, 1000));
54 if (pfd.revents & POLLIN) {
55 SYSCHECK_ERR_RETURN_NEG1(step_received = ::read(socket_fd, buffer, num_bytes - bytes_received));
56 if (step_received == 0)
57 throw std::runtime_error(
"Other end has closed the connection");
58 bytes_received += step_received;
59 buffer += step_received;
60 }
else if (pfd.revents & (POLLERR | POLLHUP)) {
61 throw std::runtime_error(
"An error occurred while waiting for the data");
63 throw std::runtime_error(
"Shared memory manager connection has timed out");
68 void send(
const void *_buffer,
size_t num_bytes) {
69 const char *buffer = (
const char*)_buffer;
70 size_t bytes_sent = 0;
72 while (bytes_sent < num_bytes) {
73 SYSCHECK_ERR_RETURN_NEG1(step_sent = ::write(socket_fd, buffer, num_bytes));
74 bytes_sent += step_sent;
88 recv(&info,
sizeof(info));
104 struct sockaddr_un address = prepare_address(path.c_str());
105 size_t len = address_length(address);
106 SYSCHECK_ERR_RETURN_NEG1(bind(socket_fd, (
struct sockaddr *)&address, len));
107 SYSCHECK_ERR_RETURN_NEG1(listen(socket_fd, 10));
108 }
catch(std::exception &e) {
109 SYSCHECK_ERR_RETURN_NEG1(close(socket_fd));
115 unlink(socket_path.c_str());
120 struct sockaddr_un addr;
121 socklen_t addr_len =
sizeof(addr);
122 SYSCHECK_ERR_RETURN_NEG1(client_fd = ::accept(socket_fd, (
struct sockaddr *)&addr, &addr_len));
126 std::string socket_path;
133 struct sockaddr_un address = prepare_address(path.c_str());
134 size_t len = address_length(address);
135 SYSCHECK_ERR_RETURN_NEG1(connect(socket_fd, (
struct sockaddr *)&address, len));
136 }
catch(std::exception &e) {
137 SYSCHECK_ERR_RETURN_NEG1(close(socket_fd));
142 void register_allocation(
AllocInfo &info) {
143 char buffer[3] = {0, 0, 0};
145 send(&info,
sizeof(info));
147 if (strcmp(buffer,
"OK") != 0)
148 throw std::runtime_error(
"Shared memory manager didn't respond with an OK");
151 void register_deallocation(
AllocInfo &info) {
152 send(&info,
sizeof(info));