133 lines
4.4 KiB
C++
133 lines
4.4 KiB
C++
#pragma once
|
|
#include <luna/Result.h>
|
|
#include <luna/SharedPtr.h>
|
|
#include <luna/StringView.h>
|
|
|
|
namespace os
|
|
{
|
|
/**
|
|
* @brief A local domain server, used to communicate between processes on the same machine.
|
|
*/
|
|
class LocalServer : public Shareable
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Create a new server object and bind it to a local address.
|
|
*
|
|
* @param path The path to use for the server socket.
|
|
* @param blocking Whether the server should block if no connections are available when calling accept().
|
|
* @return Result<SharedPtr<LocalServer>> An error, or a new server object.
|
|
*/
|
|
static Result<SharedPtr<LocalServer>> create(StringView path, bool blocking);
|
|
|
|
/**
|
|
* @brief Activate the server and start listening for connections.
|
|
*
|
|
* @param backlog The number of unaccepted connections to keep.
|
|
* @return Result<void> Whether the operation succeded.
|
|
*/
|
|
Result<void> listen(int backlog);
|
|
|
|
/**
|
|
* @brief Return the underlying socket file descriptor used by this object.
|
|
*
|
|
* @return int The file descriptor.
|
|
*/
|
|
int fd() const
|
|
{
|
|
return m_fd;
|
|
}
|
|
|
|
/**
|
|
* @brief An interface to communicate with clients connected to a local server.
|
|
*/
|
|
class Client : public Shareable
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Read arbitrary data from the client. The call will block if there is no data and the parent server
|
|
* object has not been created as non-blocking.
|
|
*
|
|
* @param buf The buffer to read data into.
|
|
* @param length The maximum amount of bytes to read.
|
|
* @return Result<usize> An error, or the number of bytes read.
|
|
*/
|
|
Result<usize> recv(u8* buf, usize length);
|
|
|
|
/**
|
|
* @brief Read an object from the client. The call will block if there is no data and the parent server
|
|
* object has not been created as non-blocking.
|
|
*
|
|
* @tparam T The type of the object.
|
|
* @param out A reference to the object to read data into.
|
|
* @return Result<void> Whether the operation succeded.
|
|
*/
|
|
template <typename T> Result<void> recv_typed(T& out)
|
|
{
|
|
TRY(recv((u8*)&out, sizeof(T)));
|
|
return {};
|
|
}
|
|
|
|
/**
|
|
* @brief Send arbitrary data to the client.
|
|
*
|
|
* @param buf The buffer to send data from.
|
|
* @param length The amount of bytes to send.
|
|
* @return Result<usize> An error, or the number of bytes actually sent.
|
|
*/
|
|
Result<usize> send(const u8* buf, usize length);
|
|
|
|
/**
|
|
* @brief Send an object to the client.
|
|
*
|
|
* @tparam T The type of the object.
|
|
* @param out A reference to the object to send data from.
|
|
* @return Result<void> Whether the operation succeded.
|
|
*/
|
|
template <typename T> Result<void> send_typed(const T& out)
|
|
{
|
|
TRY(send((const u8*)&out, sizeof(T)));
|
|
return {};
|
|
}
|
|
|
|
/**
|
|
* @brief Disconnect from the attached client.
|
|
*
|
|
* This will make any further reads on the client return ECONNRESET, and will make this object invalid.
|
|
*/
|
|
void disconnect();
|
|
|
|
/**
|
|
* @brief Return the underlying socket file descriptor used by this object.
|
|
*
|
|
* @return int The file descriptor.
|
|
*/
|
|
int fd() const
|
|
{
|
|
return m_fd;
|
|
}
|
|
|
|
Client(int fd);
|
|
~Client();
|
|
|
|
private:
|
|
int m_fd;
|
|
};
|
|
|
|
/**
|
|
* @brief Accept a new incoming connection and return a handle to it. If there are no incoming connections,
|
|
* accept() either blocks until there is one (if the object was created with blocking=true), or returns EAGAIN
|
|
* (if the object was created with blocking=false).
|
|
*
|
|
* @return Result<SharedPtr<Client>> An error, or a handle to the new connection.
|
|
*/
|
|
Result<SharedPtr<Client>> accept();
|
|
|
|
~LocalServer();
|
|
|
|
private:
|
|
int m_fd;
|
|
bool m_blocking;
|
|
};
|
|
}
|