Skip to content

Commit

Permalink
protocols: convert protocols fd to CFileDescriptor
Browse files Browse the repository at this point in the history
make most fd handling use CFileDescriptor in protocols
  • Loading branch information
gulafaran committed Jan 22, 2025
1 parent 808d8b7 commit df8957b
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 62 deletions.
16 changes: 7 additions & 9 deletions src/protocols/DRMLease.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,14 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
RESOURCE->parent = self;
});

int fd = ((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD();
if (fd < 0) {
Hyprutils::OS::CFileDescriptor fd(((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD());
if (!fd.isValid()) {
LOGM(ERR, "Failed to dup fd in lease");
return;
}

LOGM(LOG, "Sending DRMFD {} to new lease device", fd);
resource->sendDrmFd(fd);
close(fd);
LOGM(LOG, "Sending DRMFD {} to new lease device", fd.get());
resource->sendDrmFd(fd.get());

for (auto const& m : PROTO::lease->primaryDevice->offeredOutputs) {
if (m)
Expand Down Expand Up @@ -231,16 +230,15 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
}

CDRMLeaseDevice::CDRMLeaseDevice(SP<Aquamarine::CDRMBackend> drmBackend) : backend(drmBackend) {
auto drm = (Aquamarine::CDRMBackend*)drmBackend.get();
auto drm = (Aquamarine::CDRMBackend*)drmBackend.get();

auto fd = drm->getNonMasterFD();
Hyprutils::OS::CFileDescriptor fd(drm->getNonMasterFD());

if (fd < 0) {
if (!fd.isValid()) {
LOGM(ERR, "Failed to dup fd for drm node {}", drm->gpuName);
return;
}

close(fd);
success = true;
name = drm->gpuName;
}
Expand Down
1 change: 1 addition & 0 deletions src/protocols/DRMLease.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "WaylandProtocol.hpp"
#include "drm-lease-v1.hpp"
#include "../helpers/signal/Signal.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

/*
TODO: this protocol is not made for systems with multiple DRM nodes (e.g. multigpu)
Expand Down
12 changes: 5 additions & 7 deletions src/protocols/DRMSyncobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ bool CDRMSyncobjSurfaceResource::good() {
return resource->resource();
}

CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, int fd_) : fd(fd_), resource(resource_) {
CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, Hyprutils::OS::CFileDescriptor fd_) : fd(std::move(fd_)), resource(resource_) {
if UNLIKELY (!good())
return;

Expand All @@ -112,18 +112,15 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTi
resource->setOnDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });
resource->setDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });

timeline = CSyncTimeline::create(PROTO::sync->drmFD, fd);
timeline = CSyncTimeline::create(PROTO::sync->drmFD, fd.get());

if (!timeline) {
resource->error(WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, "Timeline failed importing");
return;
}
}

CDRMSyncobjTimelineResource::~CDRMSyncobjTimelineResource() {
if (fd >= 0)
close(fd);
}
CDRMSyncobjTimelineResource::~CDRMSyncobjTimelineResource() {}

SP<CDRMSyncobjTimelineResource> CDRMSyncobjTimelineResource::fromResource(wl_resource* res) {
auto data = (CDRMSyncobjTimelineResource*)(((CWpLinuxDrmSyncobjTimelineV1*)wl_resource_get_user_data(res))->data());
Expand Down Expand Up @@ -171,7 +168,8 @@ CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SP<CWpLinuxDrmSyncobjMana
});

resource->setImportTimeline([this](CWpLinuxDrmSyncobjManagerV1* r, uint32_t id, int32_t fd) {
auto RESOURCE = makeShared<CDRMSyncobjTimelineResource>(makeShared<CWpLinuxDrmSyncobjTimelineV1>(resource->client(), resource->version(), id), fd);
auto RESOURCE =
makeShared<CDRMSyncobjTimelineResource>(makeShared<CWpLinuxDrmSyncobjTimelineV1>(resource->client(), resource->version(), id), Hyprutils::OS::CFileDescriptor(fd));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
return;
Expand Down
5 changes: 3 additions & 2 deletions src/protocols/DRMSyncobj.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "WaylandProtocol.hpp"
#include "linux-drm-syncobj-v1.hpp"
#include "../helpers/signal/Signal.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CWLSurfaceResource;
class CDRMSyncobjTimelineResource;
Expand Down Expand Up @@ -33,14 +34,14 @@ class CDRMSyncobjSurfaceResource {

class CDRMSyncobjTimelineResource {
public:
CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, int fd_);
CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, Hyprutils::OS::CFileDescriptor fd_);
~CDRMSyncobjTimelineResource();
static SP<CDRMSyncobjTimelineResource> fromResource(wl_resource*);

bool good();

WP<CDRMSyncobjTimelineResource> self;
int fd = -1;
Hyprutils::OS::CFileDescriptor fd;
SP<CSyncTimeline> timeline;

private:
Expand Down
14 changes: 6 additions & 8 deletions src/protocols/GammaControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,33 @@ CGammaControl::CGammaControl(SP<CZwlrGammaControlV1> resource_, wl_resource* out
resource->setOnDestroy([this](CZwlrGammaControlV1* gamma) { PROTO::gamma->destroyGammaControl(this); });

resource->setSetGamma([this](CZwlrGammaControlV1* gamma, int32_t fd) {
Hyprutils::OS::CFileDescriptor gammaFd(fd);
if UNLIKELY (!pMonitor) {
LOGM(ERR, "setGamma for a dead monitor");
resource->sendFailed();
close(fd);
return;
}

LOGM(LOG, "setGamma for {}", pMonitor->szName);

int fdFlags = fcntl(fd, F_GETFL, 0);
// TODO: make CFileDescriptor getflags use F_GETFL
int fdFlags = fcntl(gammaFd.get(), F_GETFL, 0);
if UNLIKELY (fdFlags < 0) {
LOGM(ERR, "Failed to get fd flags");
resource->sendFailed();
close(fd);
return;
}

if UNLIKELY (fcntl(fd, F_SETFL, fdFlags | O_NONBLOCK) < 0) {
// TODO: make CFileDescriptor setflags use F_SETFL
if UNLIKELY (fcntl(gammaFd.get(), F_SETFL, fdFlags | O_NONBLOCK) < 0) {
LOGM(ERR, "Failed to set fd flags");
resource->sendFailed();
close(fd);
return;
}

ssize_t readBytes = pread(fd, gammaTable.data(), gammaTable.size() * sizeof(uint16_t), 0);
ssize_t readBytes = pread(gammaFd.get(), gammaTable.data(), gammaTable.size() * sizeof(uint16_t), 0);
if (readBytes < 0 || (size_t)readBytes != gammaTable.size() * sizeof(uint16_t)) {
LOGM(ERR, "Failed to read bytes");
close(fd);

if ((size_t)readBytes != gammaTable.size() * sizeof(uint16_t)) {
gamma->error(ZWLR_GAMMA_CONTROL_V1_ERROR_INVALID_GAMMA, "Gamma ramps size mismatch");
Expand All @@ -85,7 +84,6 @@ CGammaControl::CGammaControl(SP<CZwlrGammaControlV1> resource_, wl_resource* out
}

gammaTableSet = true;
close(fd);

// translate the table to AQ format
std::vector<uint16_t> red, green, blue;
Expand Down
15 changes: 6 additions & 9 deletions src/protocols/LinuxDMABUF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,18 +232,18 @@ void CLinuxDMABBUFParamsResource::create(uint32_t id) {
}

bool CLinuxDMABBUFParamsResource::commence() {
if (PROTO::linuxDma->mainDeviceFD < 0)
if (!PROTO::linuxDma->mainDeviceFD.isValid())
return true;

for (int i = 0; i < attrs->planes; i++) {
uint32_t handle = 0;

if (drmPrimeFDToHandle(PROTO::linuxDma->mainDeviceFD, attrs->fds.at(i), &handle)) {
if (drmPrimeFDToHandle(PROTO::linuxDma->mainDeviceFD.get(), attrs->fds.at(i), &handle)) {
LOGM(ERR, "Failed to import dmabuf fd");
return false;
}

if (drmCloseBufferHandle(PROTO::linuxDma->mainDeviceFD, handle)) {
if (drmCloseBufferHandle(PROTO::linuxDma->mainDeviceFD.get(), handle)) {
LOGM(ERR, "Failed to close dmabuf handle");
return false;
}
Expand Down Expand Up @@ -474,9 +474,9 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const

if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
const char* name = device->nodes[DRM_NODE_RENDER];
mainDeviceFD = open(name, O_RDWR | O_CLOEXEC);
mainDeviceFD = Hyprutils::OS::CFileDescriptor(open(name, O_RDWR | O_CLOEXEC));
drmFreeDevice(&device);
if (mainDeviceFD < 0) {
if (!mainDeviceFD.isValid()) {
LOGM(ERR, "failed to open drm dev, disabling linux dmabuf");
removeGlobal();
return;
Expand Down Expand Up @@ -521,10 +521,7 @@ void CLinuxDMABufV1Protocol::resetFormatTable() {
formatTable = std::move(newFormatTable);
}

CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() {
if (mainDeviceFD >= 0)
close(mainDeviceFD);
}
CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() {}

void CLinuxDMABufV1Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CLinuxDMABUFResource>(makeShared<CZwpLinuxDmabufV1>(client, ver, id)));
Expand Down
2 changes: 1 addition & 1 deletion src/protocols/LinuxDMABUF.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol {

UP<CDMABUFFormatTable> formatTable;
dev_t mainDevice;
int mainDeviceFD = -1;
Hyprutils::OS::CFileDescriptor mainDeviceFD;

friend class CLinuxDMABUFResource;
friend class CLinuxDMABUFFeedbackResource;
Expand Down
20 changes: 9 additions & 11 deletions src/protocols/SecurityContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ static int onCloseFdEvent(int fd, uint32_t mask, void* data) {
return 0;
}

SP<CSecurityContextSandboxedClient> CSecurityContextSandboxedClient::create(int clientFD_) {
auto p = SP<CSecurityContextSandboxedClient>(new CSecurityContextSandboxedClient(clientFD_));
SP<CSecurityContextSandboxedClient> CSecurityContextSandboxedClient::create(Hyprutils::OS::CFileDescriptor clientFD_) {
auto p = SP<CSecurityContextSandboxedClient>(new CSecurityContextSandboxedClient(std::move(clientFD_)));
if (!p->client)
return nullptr;
return p;
Expand All @@ -27,8 +27,8 @@ static void onSecurityContextClientDestroy(wl_listener* l, void* d) {
client->onDestroy();
}

CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_) : clientFD(clientFD_) {
client = wl_client_create(g_pCompositor->m_sWLDisplay, clientFD);
CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(Hyprutils::OS::CFileDescriptor clientFD_) : clientFD(std::move(clientFD_)) {
client = wl_client_create(g_pCompositor->m_sWLDisplay, clientFD.get());
if (!client)
return;

Expand All @@ -41,7 +41,6 @@ CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_)
CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() {
wl_list_remove(&destroyListener.listener.link);
wl_list_init(&destroyListener.listener.link);
close(clientFD);
}

void CSecurityContextSandboxedClient::onDestroy() {
Expand Down Expand Up @@ -113,8 +112,8 @@ CSecurityContext::CSecurityContext(SP<CWpSecurityContextV1> resource_, int liste

LOGM(LOG, "security_context at 0x{:x} commits", (uintptr_t)this);

listenSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, listenFD, WL_EVENT_READABLE, ::onListenFdEvent, this);
closeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, closeFD, 0, ::onCloseFdEvent, this);
listenSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, listenFD.get(), WL_EVENT_READABLE, ::onListenFdEvent, this);
closeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, closeFD.get(), 0, ::onCloseFdEvent, this);

if (!listenSource || !closeSource) {
r->noMemory();
Expand Down Expand Up @@ -144,16 +143,15 @@ void CSecurityContext::onListen(uint32_t mask) {
if (!(mask & WL_EVENT_READABLE))
return;

int clientFD = accept(listenFD, nullptr, nullptr);
if UNLIKELY (clientFD < 0) {
Hyprutils::OS::CFileDescriptor clientFD(accept(listenFD.get(), nullptr, nullptr));
if UNLIKELY (!clientFD.isValid()) {
LOGM(ERR, "security_context at 0x{:x} couldn't accept", (uintptr_t)this);
return;
}

auto newClient = CSecurityContextSandboxedClient::create(clientFD);
auto newClient = CSecurityContextSandboxedClient::create(std::move(clientFD));
if UNLIKELY (!newClient) {
LOGM(ERR, "security_context at 0x{:x} couldn't create a client", (uintptr_t)this);
close(clientFD);
return;
}

Expand Down
19 changes: 10 additions & 9 deletions src/protocols/SecurityContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "security-context-v1.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CSecurityContext {
public:
CSecurityContext(SP<CWpSecurityContextV1> resource_, int listenFD_, int closeFD_);
~CSecurityContext();

bool good();
bool good();

std::string sandboxEngine, appID, instanceID;
int listenFD = -1, closeFD = -1;
std::string sandboxEngine, appID, instanceID;
Hyprutils::OS::CFileDescriptor listenFD, closeFD;

void onListen(uint32_t mask);
void onClose(uint32_t mask);
void onListen(uint32_t mask);
void onClose(uint32_t mask);

private:
SP<CWpSecurityContextV1> resource;
Expand Down Expand Up @@ -45,18 +46,18 @@ struct SCSecurityContextSandboxedClientDestroyWrapper {

class CSecurityContextSandboxedClient {
public:
static SP<CSecurityContextSandboxedClient> create(int clientFD);
static SP<CSecurityContextSandboxedClient> create(Hyprutils::OS::CFileDescriptor clientFD);
~CSecurityContextSandboxedClient();

void onDestroy();

SCSecurityContextSandboxedClientDestroyWrapper destroyListener;

private:
CSecurityContextSandboxedClient(int clientFD_);
CSecurityContextSandboxedClient(Hyprutils::OS::CFileDescriptor clientFD_);

wl_client* client = nullptr;
int clientFD = -1;
wl_client* client = nullptr;
Hyprutils::OS::CFileDescriptor clientFD;

friend class CSecurityContextProtocol;
friend class CSecurityContext;
Expand Down
9 changes: 3 additions & 6 deletions src/protocols/VirtualKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,19 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1>
});

resource->setKeymap([this](CZwpVirtualKeyboardV1* r, uint32_t fmt, int32_t fd, uint32_t len) {
auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
Hyprutils::OS::CFileDescriptor keymapFd(fd);
if UNLIKELY (!xkbContext) {
LOGM(ERR, "xkbContext creation failed");
r->noMemory();
close(fd);
return;
}

auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, fd, 0);
auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, keymapFd.get(), 0);
if UNLIKELY (keymapData == MAP_FAILED) {
LOGM(ERR, "keymapData alloc failed");
xkb_context_unref(xkbContext);
r->noMemory();
close(fd);
return;
}

Expand All @@ -75,7 +74,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1>
LOGM(ERR, "xkbKeymap creation failed");
xkb_context_unref(xkbContext);
r->noMemory();
close(fd);
return;
}

Expand All @@ -86,7 +84,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1>

xkb_keymap_unref(xkbKeymap);
xkb_context_unref(xkbContext);
close(fd);
});

name = "hl-virtual-keyboard";
Expand Down
1 change: 1 addition & 0 deletions src/protocols/VirtualKeyboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "WaylandProtocol.hpp"
#include "virtual-keyboard-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CVirtualKeyboardV1Resource {
public:
Expand Down

0 comments on commit df8957b

Please sign in to comment.