Luna/libos/src/LocalClient.cpp

69 lines
1.5 KiB
C++

/**
* @file LocalClient.cpp
* @author apio (cloudapio.eu)
* @brief UNIX local domain client class.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <errno.h>
#include <fcntl.h>
#include <os/LocalClient.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
namespace os
{
Result<OwnedPtr<LocalClient>> LocalClient::connect(StringView path, bool blocking)
{
auto client = TRY(make_owned<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;
}
}