Skip to content
Snippets Groups Projects

Draft: Resolve "Unix Socket Server schreiben"

Merged Leon Dietrich requested to merge 3-unix-socket-server-schreiben into master
2 files
+ 40
3
Compare changes
  • Side-by-side
  • Inline
Files
2
#include "net/unix_socket_server.hpp"
#include <filesystem>
#include <sstream>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -12,6 +15,14 @@
namespace rmrf::net {
std::string get_usocket_path(const socketaddr& addr) {
if (addr.family() != AF_UNIX) {
return std::string();
}
return std::string(((sockaddr_un*) addr.ptr())->sun_path);
}
auto_fd construct_server_fd(const socketaddr& addr) {
if (addr.family() != AF_UNIX) {
throw netio_exception("Expected a UNIX socket file path.");
@@ -25,12 +36,28 @@ auto_fd construct_server_fd(const socketaddr& addr) {
}
if (auto error = bind(socket_fd.get(), addr.ptr(), addr.size()); error != 0) {
throw netio_exception("Failed to bind to socket " + addr.str());
std::stringstream ss;
ss << "Failed to bind to socket " + addr.str() << ".";
const auto p = std::filesystem::path(get_usocket_path(addr));
if (std::filesystem::exists(p)) {
ss << " Reason: The file already exists.";
if (std::filesystem::is_socket(p)) {
ss << " It is also a socket. Is the application already running?";
}
} else {
ss << " Is there buffer space avaiable and do you have the permission to create a socket there?";
}
throw netio_exception(ss.str());
}
make_socket_nonblocking(socket_fd);
if (listen(socket_fd.get(), 5) == -1) {
// We already created the socket and close won't remove the file thus we need to unlink it.
unlink(get_usocket_path(addr).c_str());
throw netio_exception("Failed to enable listening mode for raw socket");
}
@@ -40,11 +67,16 @@ auto_fd construct_server_fd(const socketaddr& addr) {
unix_socket_server::unix_socket_server(
const socketaddr& socket_identifier,
async_server_socket::accept_handler_type client_listener_
) : async_server_socket{construct_server_fd(socket_identifier)} {
) : async_server_socket{construct_server_fd(socket_identifier)}, socket_path{get_usocket_path(socket_identifier)} {
this->set_accept_handler(client_listener_);
}
unix_socket_server::~unix_socket_server() {}
unix_socket_server::~unix_socket_server() {
if (this->socket_path.length() > 0) {
// We're ignoring potential errors as there's nothing we can do about it anyway.
unlink(this->socket_path.c_str());
}
}
std::shared_ptr<connection_client> unix_socket_server::await_raw_socket_incomming(const auto_fd& server_socket) {
auto client_socket = auto_fd{accept(server_socket.get(), nullptr, nullptr)};
Loading