Add a display server and graphical user interface #38

Merged
apio merged 103 commits from display-server into main 2023-09-20 18:49:21 +00:00
3 changed files with 150 additions and 0 deletions
Showing only changes of commit 03096680ae - Show all commits

View File

@ -15,6 +15,7 @@ set(SOURCES
src/Prompt.cpp
src/Security.cpp
src/LocalServer.cpp
src/LocalClient.cpp
)
add_library(os ${SOURCES})

View File

@ -0,0 +1,90 @@
#pragma once
#include <luna/SharedPtr.h>
#include <luna/StringView.h>
namespace os
{
/**
* @brief A client used to connect to a local server socket.
*/
class LocalClient : public Shareable
{
public:
/**
* @brief Create a new client object and connect it to a local server.
*
* @param path The path of the server socket to connect to.
* @param blocking Whether the client should block if no data is available and recv() is called.
* @return Result<SharedPtr<LocalClient>> An error, or a new client object.
*/
static Result<SharedPtr<LocalClient>> connect(StringView path, bool blocking);
/**
* @brief Return the underlying socket file descriptor used by this object.
*
* @return int The file descriptor.
*/
int fd() const
{
return m_fd;
}
/**
* @brief Read arbitrary data from the server. The call will block if there is no data and this 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 server. The call will block if there is no data and this 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 server.
*
* @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 server.
*
* @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 server.
*
* This will make any further reads on this connection return ECONNRESET, and will make this object invalid.
*/
void disconnect();
~LocalClient();
private:
int m_fd;
};
}

59
libos/src/LocalClient.cpp Normal file
View File

@ -0,0 +1,59 @@
#include <errno.h>
#include <fcntl.h>
#include <os/LocalClient.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
namespace os
{
Result<SharedPtr<LocalClient>> LocalClient::connect(StringView path, bool blocking)
{
auto client = TRY(make_shared<LocalClient>());
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd < 0) return err(errno);
struct sockaddr_un un;
un.sun_family = AF_UNIX;
strncpy(un.sun_path, path.chars(), sizeof(un.sun_path));
if (::connect(sockfd, (struct sockaddr*)&un, sizeof(un)) < 0)
{
close(sockfd);
return err(errno);
}
if (!blocking) { fcntl(sockfd, F_SETFL, O_NONBLOCK); }
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
client->m_fd = sockfd;
return client;
}
LocalClient::~LocalClient()
{
close(m_fd);
}
Result<usize> LocalClient::recv(u8* buf, usize length)
{
ssize_t nread = read(m_fd, buf, length);
if (nread < 0) return err(errno);
return nread;
}
Result<usize> LocalClient::send(const u8* buf, usize length)
{
ssize_t nwrite = write(m_fd, buf, length);
if (nwrite < 0) return err(errno);
return nwrite;
}
void LocalClient::disconnect()
{
close(m_fd);
m_fd = -1;
}
}