diff --git a/runtime/Makefile b/runtime/Makefile index 6a7014a..b77d26e 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,6 +1,6 @@ CXX_FLAGS = \ - -std=c++20 \ + -std=c++23 \ -Og \ -fsanitize=address,undefined \ -pedantic -pedantic-errors \ diff --git a/runtime/compile_flags.txt b/runtime/compile_flags.txt index c79d0c3..9b17ba7 100644 --- a/runtime/compile_flags.txt +++ b/runtime/compile_flags.txt @@ -1,5 +1,5 @@ -xc++ --std=c++20 +-std=c++23 -pedantic -pedantic-errors -Wall diff --git a/runtime/rpc_server.cpp b/runtime/rpc_server.cpp index 18d9749..8264e28 100644 --- a/runtime/rpc_server.cpp +++ b/runtime/rpc_server.cpp @@ -1 +1,84 @@ #include "rpc_server.hpp" +#include +#include + +auto slige_rpc::ClientSocket::Read( + uint8_t* buffer, size_t length) -> std::variant +{ + ssize_t bytes_read = recv(fd, buffer, length, 0); + if (bytes_read < 0) { + return Ewwow { .message = "unable to read" }; + } + return (size_t)bytes_read; +}; + +auto slige_rpc::ClientSocket::Write( + uint8_t* buffer, size_t length) -> std::variant +{ + ssize_t bytes_written = send(fd, buffer, length, 0); + if (bytes_written < 0) { + return Ewwow { .message = "unable to write" }; + } + return (size_t)bytes_written; +}; + +auto slige_rpc::Socket::Connect() + -> std::variant +{ + int socket_fd; + if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return { Ewwow { .message = "could not get socket" } }; + } + // TODO: + // 1) does address (presumably 'socket) + // live as long as child socket ('client)? + // - immediate answer is no + // 2) does it need to? + if (connect(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { + return { Ewwow { + .message = "could not connect, is the server running?" } }; + } + return { ClientSocket(socket_fd) }; +} + +auto slige_rpc::ServerSocket::Accept() + -> std::variant +{ + unsigned int address_size = sizeof(address); + // TODO: + // 1) does address (presumably 'server) + // live as long as child socket ('socket)? + // - immediate answer is no + // 2) does it need to? + int client = accept(fd, (struct sockaddr*)&address, &address_size); + if (client < 0) { + return Ewwow { .message = "could not accept" }; + } + return client; + return { ClientSocket(client) }; +} + +auto slige_rpc::Socket::Bind() -> std::variant +{ + int socket_fd; + if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return { Ewwow { .message = "could not get socket" } }; + } + // TODO: + // 1) does address (presumably 'socket) + // live as long as child socket ('server)? + // - immediate answer is no + // 2) does it need to? + if (bind(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { + return { Ewwow { .message = "could not bind" } }; + } + + if (listen(socket_fd, 0) < 0) { + return { Ewwow { .message = "could not listen" } }; + } + // TODO: + // 1) does this address get moved, copied or cloned? + // it should be represented as a u32, + // so copying should be fine - but does it? + return { ServerSocket(socket_fd, address) }; +} diff --git a/runtime/rpc_server.hpp b/runtime/rpc_server.hpp index 478277f..14c77c2 100644 --- a/runtime/rpc_server.hpp +++ b/runtime/rpc_server.hpp @@ -1,5 +1,13 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include + namespace slige_rpc { class RpcServer { @@ -7,4 +15,60 @@ public: private: }; +struct Ewwow { + std::string message; +}; + +namespace { + class ClientSocket { + public: + ~ClientSocket() { close(fd); }; + ClientSocket(int fd) + : fd(fd) + { + } + auto Read( + uint8_t* buffer, size_t length) -> std::variant; + auto Write( + uint8_t* buffer, size_t length) -> std::variant; + + private: + int fd; + }; + + class ServerSocket { + public: + ServerSocket(int fd, sockaddr_in address) + : fd(fd) + , address(address) + { + } + ~ServerSocket() { close(fd); }; + auto Accept() -> std::variant; + + private: + int fd; + sockaddr_in address; + }; } + +class Socket { +public: + Socket(uint16_t port) + { + address = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr = { .s_addr = inet_addr("127.0.0.1") }, + .sin_zero = { 0 }, + }; + } + + auto Connect() -> std::variant; + auto Bind() -> std::variant; + +private: + sockaddr_in address; +}; + +};