summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config/ConfigWatcher.cpp25
-rw-r--r--src/config/ConfigWatcher.hpp15
-rw-r--r--src/debug/HyprCtl.cpp18
-rw-r--r--src/debug/HyprCtl.hpp11
-rw-r--r--src/devices/IKeyboard.cpp26
-rw-r--r--src/devices/IKeyboard.hpp3
-rw-r--r--src/helpers/MiscFunctions.cpp44
-rw-r--r--src/helpers/MiscFunctions.hpp5
-rw-r--r--src/helpers/Monitor.cpp17
-rw-r--r--src/helpers/Monitor.hpp1
-rw-r--r--src/helpers/sync/SyncTimeline.cpp26
-rw-r--r--src/helpers/sync/SyncTimeline.hpp32
-rw-r--r--src/managers/EventManager.cpp44
-rw-r--r--src/managers/EventManager.hpp14
-rw-r--r--src/managers/KeybindManager.cpp29
-rw-r--r--src/managers/eventLoop/EventLoopManager.cpp13
-rw-r--r--src/managers/eventLoop/EventLoopManager.hpp3
-rw-r--r--src/protocols/DRMLease.cpp17
-rw-r--r--src/protocols/DRMLease.hpp1
-rw-r--r--src/protocols/DRMSyncobj.cpp12
-rw-r--r--src/protocols/DRMSyncobj.hpp7
-rw-r--r--src/protocols/DataDeviceWlr.cpp12
-rw-r--r--src/protocols/DataDeviceWlr.hpp3
-rw-r--r--src/protocols/GammaControl.cpp15
-rw-r--r--src/protocols/InputMethodV2.cpp11
-rw-r--r--src/protocols/LinuxDMABUF.cpp37
-rw-r--r--src/protocols/LinuxDMABUF.hpp9
-rw-r--r--src/protocols/PrimarySelection.cpp12
-rw-r--r--src/protocols/PrimarySelection.hpp3
-rw-r--r--src/protocols/SecurityContext.cpp21
-rw-r--r--src/protocols/SecurityContext.hpp19
-rw-r--r--src/protocols/VirtualKeyboard.cpp10
-rw-r--r--src/protocols/VirtualKeyboard.hpp1
-rw-r--r--src/protocols/core/DataDevice.cpp12
-rw-r--r--src/protocols/core/DataDevice.hpp3
-rw-r--r--src/protocols/core/Seat.cpp29
-rw-r--r--src/protocols/core/Shm.cpp23
-rw-r--r--src/protocols/core/Shm.hpp14
-rw-r--r--src/protocols/types/DataDevice.hpp9
-rw-r--r--src/render/OpenGL.cpp41
-rw-r--r--src/render/OpenGL.hpp13
-rw-r--r--src/render/Renderer.cpp20
-rw-r--r--src/xwayland/Dnd.cpp4
-rw-r--r--src/xwayland/Dnd.hpp3
-rw-r--r--src/xwayland/Server.cpp175
-rw-r--r--src/xwayland/Server.hpp31
-rw-r--r--src/xwayland/XDataSource.cpp13
-rw-r--r--src/xwayland/XDataSource.hpp5
-rw-r--r--src/xwayland/XWM.cpp20
-rw-r--r--src/xwayland/XWM.hpp27
50 files changed, 427 insertions, 531 deletions
diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp
index c0a9c591..8d086bac 100644
--- a/src/config/ConfigWatcher.cpp
+++ b/src/config/ConfigWatcher.cpp
@@ -5,27 +5,24 @@
#include <fcntl.h>
#include <unistd.h>
+using namespace Hyprutils::OS;
+
CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) {
- if (m_inotifyFd < 0) {
+ if (!m_inotifyFd.isValid()) {
Debug::log(ERR, "CConfigWatcher couldn't open an inotify node. Config will not be automatically reloaded");
return;
}
- const int FLAGS = fcntl(m_inotifyFd, F_GETFL, 0);
- if (fcntl(m_inotifyFd, F_SETFL, FLAGS | O_NONBLOCK) < 0) {
+ // TODO: make CFileDescriptor take F_GETFL, F_SETFL
+ const int FLAGS = fcntl(m_inotifyFd.get(), F_GETFL, 0);
+ if (fcntl(m_inotifyFd.get(), F_SETFL, FLAGS | O_NONBLOCK) < 0) {
Debug::log(ERR, "CConfigWatcher couldn't non-block inotify node. Config will not be automatically reloaded");
- close(m_inotifyFd);
- m_inotifyFd = -1;
+ m_inotifyFd.reset();
return;
}
}
-CConfigWatcher::~CConfigWatcher() {
- if (m_inotifyFd >= 0)
- close(m_inotifyFd);
-}
-
-int CConfigWatcher::getInotifyFD() {
+CFileDescriptor& CConfigWatcher::getInotifyFD() {
return m_inotifyFd;
}
@@ -38,7 +35,7 @@ void CConfigWatcher::setWatchList(const std::vector<std::string>& paths) {
// cleanup old paths
for (auto& watch : m_watches) {
- inotify_rm_watch(m_inotifyFd, watch.wd);
+ inotify_rm_watch(m_inotifyFd.get(), watch.wd);
}
m_watches.clear();
@@ -46,7 +43,7 @@ void CConfigWatcher::setWatchList(const std::vector<std::string>& paths) {
// add new paths
for (const auto& path : paths) {
m_watches.emplace_back(SInotifyWatch{
- .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY),
+ .wd = inotify_add_watch(m_inotifyFd.get(), path.c_str(), IN_MODIFY),
.file = path,
});
}
@@ -58,7 +55,7 @@ void CConfigWatcher::setOnChange(const std::function<void(const SConfigWatchEven
void CConfigWatcher::onInotifyEvent() {
inotify_event ev;
- while (read(m_inotifyFd, &ev, sizeof(ev)) > 0) {
+ while (read(m_inotifyFd.get(), &ev, sizeof(ev)) > 0) {
const auto WD = std::ranges::find_if(m_watches.begin(), m_watches.end(), [wd = ev.wd](const auto& e) { return e.wd == wd; });
if (WD == m_watches.end()) {
diff --git a/src/config/ConfigWatcher.hpp b/src/config/ConfigWatcher.hpp
index c36ecd17..97945689 100644
--- a/src/config/ConfigWatcher.hpp
+++ b/src/config/ConfigWatcher.hpp
@@ -3,20 +3,21 @@
#include <vector>
#include <string>
#include <functional>
+#include <hyprutils/os/FileDescriptor.hpp>
class CConfigWatcher {
public:
CConfigWatcher();
- ~CConfigWatcher();
+ ~CConfigWatcher() = default;
struct SConfigWatchEvent {
std::string file;
};
- int getInotifyFD();
- void setWatchList(const std::vector<std::string>& paths);
- void setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn);
- void onInotifyEvent();
+ Hyprutils::OS::CFileDescriptor& getInotifyFD();
+ void setWatchList(const std::vector<std::string>& paths);
+ void setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn);
+ void onInotifyEvent();
private:
struct SInotifyWatch {
@@ -26,7 +27,7 @@ class CConfigWatcher {
std::function<void(const SConfigWatchEvent&)> m_watchCallback;
std::vector<SInotifyWatch> m_watches;
- int m_inotifyFd = -1;
+ Hyprutils::OS::CFileDescriptor m_inotifyFd;
};
-inline UP<CConfigWatcher> g_pConfigWatcher = makeUnique<CConfigWatcher>(); \ No newline at end of file
+inline UP<CConfigWatcher> g_pConfigWatcher = makeUnique<CConfigWatcher>();
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 359428b1..cd6451e2 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -25,6 +25,7 @@
#include <hyprutils/string/String.hpp>
using namespace Hyprutils::String;
+using namespace Hyprutils::OS;
#include <aquamarine/input/Input.hpp>
#include "../config/ConfigDataValues.hpp"
@@ -1680,8 +1681,6 @@ CHyprCtl::CHyprCtl() {
CHyprCtl::~CHyprCtl() {
if (m_eventSource)
wl_event_source_remove(m_eventSource);
- if (m_iSocketFD >= 0)
- close(m_iSocketFD);
if (!m_socketPath.empty())
unlink(m_socketPath.c_str());
}
@@ -1840,10 +1839,13 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP)
return 0;
+ if (!g_pHyprCtl->m_iSocketFD.isValid())
+ return 0;
+
sockaddr_in clientAddress;
socklen_t clientSize = sizeof(clientAddress);
- const auto ACCEPTEDCONNECTION = accept4(g_pHyprCtl->m_iSocketFD, (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC);
+ const auto ACCEPTEDCONNECTION = accept4(g_pHyprCtl->m_iSocketFD.get(), (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC);
std::array<char, 1024> readBuffer;
@@ -1900,9 +1902,9 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
}
void CHyprCtl::startHyprCtlSocket() {
- m_iSocketFD = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ m_iSocketFD = CFileDescriptor{socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)};
- if (m_iSocketFD < 0) {
+ if (!m_iSocketFD.isValid()) {
Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
return;
}
@@ -1913,15 +1915,15 @@ void CHyprCtl::startHyprCtlSocket() {
strcpy(SERVERADDRESS.sun_path, m_socketPath.c_str());
- if (bind(m_iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) {
+ if (bind(m_iSocketFD.get(), (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) {
Debug::log(ERR, "Couldn't start the Hyprland Socket. (2) IPC will not work.");
return;
}
// 10 max queued.
- listen(m_iSocketFD, 10);
+ listen(m_iSocketFD.get(), 10);
Debug::log(LOG, "Hypr socket started at {}", m_socketPath);
- m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD, WL_EVENT_READABLE, hyprCtlFDTick, nullptr);
+ m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD.get(), WL_EVENT_READABLE, hyprCtlFDTick, nullptr);
}
diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp
index eed8265c..a95a5f93 100644
--- a/src/debug/HyprCtl.hpp
+++ b/src/debug/HyprCtl.hpp
@@ -4,6 +4,7 @@
#include "../helpers/MiscFunctions.hpp"
#include "../desktop/Window.hpp"
#include <functional>
+#include <hyprutils/os/FileDescriptor.hpp>
// exposed for main.cpp
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
@@ -14,12 +15,12 @@ class CHyprCtl {
CHyprCtl();
~CHyprCtl();
- std::string makeDynamicCall(const std::string& input);
- SP<SHyprCtlCommand> registerCommand(SHyprCtlCommand cmd);
- void unregisterCommand(const SP<SHyprCtlCommand>& cmd);
- std::string getReply(std::string);
+ std::string makeDynamicCall(const std::string& input);
+ SP<SHyprCtlCommand> registerCommand(SHyprCtlCommand cmd);
+ void unregisterCommand(const SP<SHyprCtlCommand>& cmd);
+ std::string getReply(std::string);
- int m_iSocketFD = -1;
+ Hyprutils::OS::CFileDescriptor m_iSocketFD;
struct {
bool all = false;
diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp
index 4623fe84..307d840b 100644
--- a/src/devices/IKeyboard.cpp
+++ b/src/devices/IKeyboard.cpp
@@ -8,6 +8,8 @@
#include <aquamarine/input/Input.hpp>
#include <cstring>
+using namespace Hyprutils::OS;
+
#define LED_COUNT 3
constexpr static std::array<const char*, 8> MODNAMES = {
@@ -41,9 +43,6 @@ void IKeyboard::clearManuallyAllocd() {
if (xkbKeymap)
xkb_keymap_unref(xkbKeymap);
- if (xkbKeymapFD >= 0)
- close(xkbKeymapFD);
-
if (xkbSymState)
xkb_state_unref(xkbSymState);
@@ -51,7 +50,7 @@ void IKeyboard::clearManuallyAllocd() {
xkbKeymap = nullptr;
xkbState = nullptr;
xkbStaticState = nullptr;
- xkbKeymapFD = -1;
+ xkbKeymapFD.reset();
}
void IKeyboard::setKeymap(const SStringRuleNames& rules) {
@@ -147,31 +146,30 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
void IKeyboard::updateKeymapFD() {
Debug::log(LOG, "Updating keymap fd for keyboard {}", deviceName);
- if (xkbKeymapFD >= 0)
- close(xkbKeymapFD);
- xkbKeymapFD = -1;
+ if (xkbKeymapFD.isValid())
+ xkbKeymapFD.reset();
auto cKeymapStr = xkb_keymap_get_as_string(xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1);
xkbKeymapString = cKeymapStr;
free(cKeymapStr);
- int rw, ro;
- if (!allocateSHMFilePair(xkbKeymapString.length() + 1, &rw, &ro))
+ CFileDescriptor rw, ro;
+ if (!allocateSHMFilePair(xkbKeymapString.length() + 1, rw, ro))
Debug::log(ERR, "IKeyboard: failed to allocate shm pair for the keymap");
else {
- auto keymapFDDest = mmap(nullptr, xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw, 0);
- close(rw);
+ auto keymapFDDest = mmap(nullptr, xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0);
+ rw.reset();
if (keymapFDDest == MAP_FAILED) {
Debug::log(ERR, "IKeyboard: failed to mmap a shm pair for the keymap");
- close(ro);
+ ro.reset();
} else {
memcpy(keymapFDDest, xkbKeymapString.c_str(), xkbKeymapString.length());
munmap(keymapFDDest, xkbKeymapString.length() + 1);
- xkbKeymapFD = ro;
+ xkbKeymapFD = std::move(ro);
}
}
- Debug::log(LOG, "Updated keymap fd to {}", xkbKeymapFD);
+ Debug::log(LOG, "Updated keymap fd to {}", xkbKeymapFD.get());
}
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp
index dce2127a..aabf4cc2 100644
--- a/src/devices/IKeyboard.hpp
+++ b/src/devices/IKeyboard.hpp
@@ -6,6 +6,7 @@
#include <optional>
#include <xkbcommon/xkbcommon.h>
+#include <hyprutils/os/FileDescriptor.hpp>
AQUAMARINE_FORWARD(IKeyboard);
@@ -96,7 +97,7 @@ class IKeyboard : public IHID {
std::string xkbFilePath = "";
std::string xkbKeymapString = "";
- int xkbKeymapFD = -1;
+ Hyprutils::OS::CFileDescriptor xkbKeymapFD;
SStringRuleNames currentRules;
int repeatRate = 0;
diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp
index 5ebb0842..f532617c 100644
--- a/src/helpers/MiscFunctions.cpp
+++ b/src/helpers/MiscFunctions.cpp
@@ -836,50 +836,48 @@ bool envEnabled(const std::string& env) {
return std::string(ENV) == "1";
}
-std::pair<int, std::string> openExclusiveShm() {
+std::pair<CFileDescriptor, std::string> openExclusiveShm() {
// Only absolute paths can be shared across different shm_open() calls
std::string name = "/" + g_pTokenManager->getRandomUUID();
for (size_t i = 0; i < 69; ++i) {
- int fd = shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fd >= 0)
- return {fd, name};
+ CFileDescriptor fd{shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600)};
+ if (fd.isValid())
+ return {std::move(fd), name};
}
- return {-1, ""};
+ return {{}, ""};
}
-int allocateSHMFile(size_t len) {
+CFileDescriptor allocateSHMFile(size_t len) {
auto [fd, name] = openExclusiveShm();
- if (fd < 0)
- return -1;
+ if (!fd.isValid())
+ return {};
shm_unlink(name.c_str());
int ret;
do {
- ret = ftruncate(fd, len);
+ ret = ftruncate(fd.get(), len);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
- close(fd);
- return -1;
+ return {};
}
- return fd;
+ return std::move(fd);
}
-bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) {
+bool allocateSHMFilePair(size_t size, CFileDescriptor& rw_fd_ptr, CFileDescriptor& ro_fd_ptr) {
auto [fd, name] = openExclusiveShm();
- if (fd < 0) {
+ if (!fd.isValid()) {
return false;
}
// CLOEXEC is guaranteed to be set by shm_open
- int ro_fd = shm_open(name.c_str(), O_RDONLY, 0);
- if (ro_fd < 0) {
+ CFileDescriptor ro_fd{shm_open(name.c_str(), O_RDONLY, 0)};
+ if (!ro_fd.isValid()) {
shm_unlink(name.c_str());
- close(fd);
return false;
}
@@ -887,24 +885,20 @@ bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) {
// Make sure the file cannot be re-opened in read-write mode (e.g. via
// "/proc/self/fd/" on Linux)
- if (fchmod(fd, 0) != 0) {
- close(fd);
- close(ro_fd);
+ if (fchmod(fd.get(), 0) != 0) {
return false;
}
int ret;
do {
- ret = ftruncate(fd, size);
+ ret = ftruncate(fd.get(), size);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
- close(fd);
- close(ro_fd);
return false;
}
- *rw_fd_ptr = fd;
- *ro_fd_ptr = ro_fd;
+ rw_fd_ptr = std::move(fd);
+ ro_fd_ptr = std::move(ro_fd);
return true;
}
diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp
index d0824284..bd288638 100644
--- a/src/helpers/MiscFunctions.hpp
+++ b/src/helpers/MiscFunctions.hpp
@@ -5,6 +5,7 @@
#include <vector>
#include <format>
#include <expected>
+#include <hyprutils/os/FileDescriptor.hpp>
#include "../SharedDefs.hpp"
#include "../macros.hpp"
@@ -35,8 +36,8 @@ double normalizeAngleRad(double ang);
std::vector<SCallstackFrameInfo> getBacktrace();
void throwError(const std::string& err);
bool envEnabled(const std::string& env);
-int allocateSHMFile(size_t len);
-bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr);
+Hyprutils::OS::CFileDescriptor allocateSHMFile(size_t len);
+bool allocateSHMFilePair(size_t size, Hyprutils::OS::CFileDescriptor& rw_fd_ptr, Hyprutils::OS::CFileDescriptor& ro_fd_ptr);
float stringToPercentage(const std::string& VALUE, const float REL);
template <typename... Args>
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index 42acf485..fc3de3aa 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -32,6 +32,7 @@
#include <ranges>
using namespace Hyprutils::String;
using namespace Hyprutils::Utils;
+using namespace Hyprutils::OS;
static int ratHandler(void* data) {
g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock());
@@ -1301,19 +1302,15 @@ bool CMonitor::attemptDirectScanout() {
// wait for the explicit fence if present, and if kms explicit is allowed
bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->syncobj->current.acquireTimeline && PSURFACE->syncobj->current.acquireTimeline->timeline && explicitOptions.explicitKMSEnabled;
- int explicitWaitFD = -1;
+ CFileDescriptor explicitWaitFD;
if (DOEXPLICIT) {
explicitWaitFD = PSURFACE->syncobj->current.acquireTimeline->timeline->exportAsSyncFileFD(PSURFACE->syncobj->current.acquirePoint);
- if (explicitWaitFD < 0)
+ if (!explicitWaitFD.isValid())
Debug::log(TRACE, "attemptDirectScanout: failed to acquire an explicit wait fd");
}
- DOEXPLICIT = DOEXPLICIT && explicitWaitFD >= 0;
+ DOEXPLICIT = DOEXPLICIT && explicitWaitFD.isValid();
- auto cleanup = CScopeGuard([explicitWaitFD, this]() {
- output->state->resetExplicitFences();
- if (explicitWaitFD >= 0)
- close(explicitWaitFD);
- });
+ auto cleanup = CScopeGuard([this]() { output->state->resetExplicitFences(); });
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
@@ -1323,8 +1320,8 @@ bool CMonitor::attemptDirectScanout() {
output->state->resetExplicitFences();
if (DOEXPLICIT) {
- Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", explicitWaitFD);
- output->state->setExplicitInFence(explicitWaitFD);
+ Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", explicitWaitFD.get());
+ output->state->setExplicitInFence(explicitWaitFD.get());
}
bool ok = output->commit();
diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp
index 2b02c30a..c67bccc5 100644
--- a/src/helpers/Monitor.hpp
+++ b/src/helpers/Monitor.hpp
@@ -16,6 +16,7 @@
#include "DamageRing.hpp"
#include <aquamarine/output/Output.hpp>
#include <aquamarine/allocator/Swapchain.hpp>
+#include <hyprutils/os/FileDescriptor.hpp>
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
enum eAutoDirs : uint8_t {
diff --git a/src/helpers/sync/SyncTimeline.cpp b/src/helpers/sync/SyncTimeline.cpp
index 16b5bd92..46b617bc 100644
--- a/src/helpers/sync/SyncTimeline.cpp
+++ b/src/helpers/sync/SyncTimeline.cpp
@@ -4,6 +4,7 @@
#include <xf86drm.h>
#include <sys/eventfd.h>
+using namespace Hyprutils::OS;
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
@@ -85,10 +86,9 @@ bool CSyncTimeline::addWaiter(const std::function<void()>& waiter, uint64_t poin
auto w = makeShared<SWaiter>();
w->fn = waiter;
w->timeline = self;
+ w->eventFd = CFileDescriptor{eventfd(0, EFD_CLOEXEC)};
- int eventFD = eventfd(0, EFD_CLOEXEC);
-
- if (eventFD < 0) {
+ if (!w->eventFd.isValid()) {
Debug::log(ERR, "CSyncTimeline::addWaiter: failed to acquire an eventfd");
return false;
}
@@ -97,19 +97,17 @@ bool CSyncTimeline::addWaiter(const std::function<void()>& waiter, uint64_t poin
.handle = handle,
.flags = flags,
.point = point,
- .fd = eventFD,
+ .fd = w->eventFd.get(),
};
if (drmIoctl(drmFD, DRM_IOCTL_SYNCOBJ_EVENTFD, &syncobjEventFD) != 0) {
Debug::log(ERR, "CSyncTimeline::addWaiter: drmIoctl failed");
- close(eventFD);
return false;
}
- w->source = wl_event_loop_add_fd(g_pEventLoopManager->m_sWayland.loop, eventFD, WL_EVENT_READABLE, ::handleWaiterFD, w.get());
+ w->source = wl_event_loop_add_fd(g_pEventLoopManager->m_sWayland.loop, w->eventFd.get(), WL_EVENT_READABLE, ::handleWaiterFD, w.get());
if (!w->source) {
Debug::log(ERR, "CSyncTimeline::addWaiter: wl_event_loop_add_fd failed");
- close(eventFD);
return false;
}
@@ -126,32 +124,32 @@ void CSyncTimeline::removeWaiter(SWaiter* w) {
std::erase_if(waiters, [w](const auto& e) { return e.get() == w; });
}
-int CSyncTimeline::exportAsSyncFileFD(uint64_t src) {
+CFileDescriptor CSyncTimeline::exportAsSyncFileFD(uint64_t src) {
int sync = -1;
uint32_t syncHandle = 0;
if (drmSyncobjCreate(drmFD, 0, &syncHandle)) {
Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjCreate failed");
- return -1;
+ return {};
}
if (drmSyncobjTransfer(drmFD, syncHandle, 0, handle, src, 0)) {
Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjTransfer failed");
drmSyncobjDestroy(drmFD, syncHandle);
- return -1;
+ return {};
}
if (drmSyncobjExportSyncFile(drmFD, syncHandle, &sync)) {
Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjExportSyncFile failed");
drmSyncobjDestroy(drmFD, syncHandle);
- return -1;
+ return {};
}
drmSyncobjDestroy(drmFD, syncHandle);
- return sync;
+ return CFileDescriptor{sync};
}
-bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, int fd) {
+bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, CFileDescriptor& fd) {
uint32_t syncHandle = 0;
if (drmSyncobjCreate(drmFD, 0, &syncHandle)) {
@@ -159,7 +157,7 @@ bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, int fd) {
return false;
}
- if (drmSyncobjImportSyncFile(drmFD, syncHandle, fd)) {
+ if (drmSyncobjImportSyncFile(drmFD, syncHandle, fd.get())) {
Debug::log(ERR, "importFromSyncFileFD: drmSyncobjImportSyncFile failed");
drmSyncobjDestroy(drmFD, syncHandle);
return false;
diff --git a/src/helpers/sync/SyncTimeline.hpp b/src/helpers/sync/SyncTimeline.hpp
index 88ad4921..ba65e004 100644
--- a/src/helpers/sync/SyncTimeline.hpp
+++ b/src/helpers/sync/SyncTimeline.hpp
@@ -4,6 +4,7 @@
#include <optional>
#include <vector>
#include <functional>
+#include <hyprutils/os/FileDescriptor.hpp>
#include "../memory/Memory.hpp"
/*
@@ -20,26 +21,27 @@ class CSyncTimeline {
~CSyncTimeline();
struct SWaiter {
- std::function<void()> fn;
- wl_event_source* source = nullptr;
- WP<CSyncTimeline> timeline;
+ std::function<void()> fn;
+ wl_event_source* source = nullptr;
+ WP<CSyncTimeline> timeline;
+ Hyprutils::OS::CFileDescriptor eventFd;
};
// check if the timeline point has been signaled
// flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT or DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
// std::nullopt on fail
- std::optional<bool> check(uint64_t point, uint32_t flags);
-
- bool addWaiter(const std::function<void()>& waiter, uint64_t point, uint32_t flags);
- void removeWaiter(SWaiter*);
- int exportAsSyncFileFD(uint64_t src);
- bool importFromSyncFileFD(uint64_t dst, int fd);
- bool transfer(SP<CSyncTimeline> from, uint64_t fromPoint, uint64_t toPoint);
- void signal(uint64_t point);
-
- int drmFD = -1;
- uint32_t handle = 0;
- WP<CSyncTimeline> self;
+ std::optional<bool> check(uint64_t point, uint32_t flags);
+
+ bool addWaiter(const std::function<void()>& waiter, uint64_t point, uint32_t flags);
+ void removeWaiter(SWaiter*);
+ Hyprutils::OS::CFileDescriptor exportAsSyncFileFD(uint64_t src);
+ bool importFromSyncFileFD(uint64_t dst, Hyprutils::OS::CFileDescriptor& fd);
+ bool transfer(SP<CSyncTimeline> from, uint64_t fromPoint, uint64_t toPoint);
+ void signal(uint64_t point);
+
+ int drmFD = -1;
+ uint32_t handle = 0;
+ WP<CSyncTimeline> self;
private:
CSyncTimeline() = default;
diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp
index fc55b472..6231f0bc 100644
--- a/src/managers/EventManager.cpp
+++ b/src/managers/EventManager.cpp
@@ -9,9 +9,10 @@
#include <sys/un.h>
#include <unistd.h>
#include <cstring>
+using namespace Hyprutils::OS;
CEventManager::CEventManager() : m_iSocketFD(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) {
- if (m_iSocketFD < 0) {
+ if (!m_iSocketFD.isValid()) {
Debug::log(ERR, "Couldn't start the Hyprland Socket 2. (1) IPC will not work.");
return;
}
@@ -25,31 +26,27 @@ CEventManager::CEventManager() : m_iSocketFD(socket(AF_UNIX, SOCK_STREAM | SOCK_
strncpy(SERVERADDRESS.sun_path, PATH.c_str(), sizeof(SERVERADDRESS.sun_path) - 1);
- if (bind(m_iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) {
+ if (bind(m_iSocketFD.get(), (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) {
Debug::log(ERR, "Couldn't bind the Hyprland Socket 2. (3) IPC will not work.");
return;
}
// 10 max queued.
- if (listen(m_iSocketFD, 10) < 0) {
+ if (listen(m_iSocketFD.get(), 10) < 0) {
Debug::log(ERR, "Couldn't listen on the Hyprland Socket 2. (4) IPC will not work.");
return;
}
- m_pEventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD, WL_EVENT_READABLE, onClientEvent, nullptr);
+ m_pEventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD.get(), WL_EVENT_READABLE, onClientEvent, nullptr);
}
CEventManager::~CEventManager() {
for (const auto& client : m_vClients) {
wl_event_source_remove(client.eventSource);
- close(client.fd);
}
if (m_pEventSource != nullptr)
wl_event_source_remove(m_pEventSource);
-
- if (m_iSocketFD >= 0)
- close(m_iSocketFD);
}
int CEventManager::onServerEvent(int fd, uint32_t mask, void* data) {
@@ -66,33 +63,31 @@ int CEventManager::onServerEvent(int fd, uint32_t mask) {
wl_event_source_remove(m_pEventSource);
m_pEventSource = nullptr;
- close(fd);
- m_iSocketFD = -1;
+ m_iSocketFD.reset();
return 0;
}
- sockaddr_in clientAddress;
- socklen_t clientSize = sizeof(clientAddress);
- const auto ACCEPTEDCONNECTION = accept4(m_iSocketFD, (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC | SOCK_NONBLOCK);
- if (ACCEPTEDCONNECTION < 0) {
+ sockaddr_in clientAddress;
+ socklen_t clientSize = sizeof(clientAddress);
+ CFileDescriptor ACCEPTEDCONNECTION{accept4(m_iSocketFD.get(), (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC | SOCK_NONBLOCK)};
+ if (!ACCEPTEDCONNECTION.isValid()) {
if (errno != EAGAIN) {
Debug::log(ERR, "Socket2 failed receiving connection, errno: {}", errno);
wl_event_source_remove(m_pEventSource);
m_pEventSource = nullptr;
- close(fd);
- m_iSocketFD = -1;
+ m_iSocketFD.reset();
}
return 0;
}
- Debug::log(LOG, "Socket2 accepted a new client at FD {}", ACCEPTEDCONNECTION);
+ Debug::log(LOG, "Socket2 accepted a new client at FD {}", ACCEPTEDCONNECTION.get());
// add to event loop so we can close it when we need to
- auto* eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, ACCEPTEDCONNECTION, 0, onServerEvent, nullptr);
+ auto* eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, ACCEPTEDCONNECTION.get(), 0, onServerEvent, nullptr);
m_vClients.emplace_back(SClient{
- ACCEPTEDCONNECTION,
+ std::move(ACCEPTEDCONNECTION),
{},
eventSource,
});
@@ -113,7 +108,7 @@ int CEventManager::onClientEvent(int fd, uint32_t mask) {
// send all queued events
while (!CLIENTIT->events.empty()) {
const auto& event = CLIENTIT->events.front();
- if (write(CLIENTIT->fd, event->c_str(), event->length()) < 0)
+ if (write(CLIENTIT->fd.get(), event->c_str(), event->length()) < 0)
break;
CLIENTIT->events.erase(CLIENTIT->events.begin());
@@ -128,13 +123,12 @@ int CEventManager::onClientEvent(int fd, uint32_t mask) {
}
std::vector<CEventManager::SClient>::iterator CEventManager::findClientByFD(int fd) {
- return std::find_if(m_vClients.begin(), m_vClients.end(), [fd](const auto& client) { return client.fd == fd; });
+ return std::find_if(m_vClients.begin(), m_vClients.end(), [fd](const auto& client) { return client.fd.get() == fd; });
}
std::vector<CEventManager::SClient>::iterator CEventManager::removeClientByFD(int fd) {
const auto CLIENTIT = findClientByFD(fd);
wl_event_source_remove(CLIENTIT->eventSource);
- close(fd);
return m_vClients.erase(CLIENTIT);
}
@@ -157,11 +151,11 @@ void CEventManager::postEvent(const SHyprIPCEvent& event) {
for (auto it = m_vClients.begin(); it != m_vClients.end();) {
// try to send the event immediately if the queue is empty
const auto QUEUESIZE = it->events.size();
- if (QUEUESIZE > 0 || write(it->fd, sharedEvent->c_str(), sharedEvent->length()) < 0) {
+ if (QUEUESIZE > 0 || write(it->fd.get(), sharedEvent->c_str(), sharedEvent->length()) < 0) {
if (QUEUESIZE >= MAX_QUEUED_EVENTS) {
// too many events queued, remove the client
- Debug::log(ERR, "Socket2 fd {} overflowed event queue, removing", it->fd);
- it = removeClientByFD(it->fd);
+ Debug::log(ERR, "Socket2 fd {} overflowed event queue, removing", it->fd.get());
+ it = removeClientByFD(it->fd.get());
continue;
}
diff --git a/src/managers/EventManager.hpp b/src/managers/EventManager.hpp
index 6b506d33..c8335d20 100644
--- a/src/managers/EventManager.hpp
+++ b/src/managers/EventManager.hpp
@@ -1,6 +1,6 @@
#pragma once
#include <vector>
-
+#include <hyprutils/os/FileDescriptor.hpp>
#include "../defines.hpp"
#include "../helpers/memory/Memory.hpp"
@@ -26,19 +26,19 @@ class CEventManager {
int onClientEvent(int fd, uint32_t mask);
struct SClient {
- int fd = -1;
- std::vector<SP<std::string>> events;
- wl_event_source* eventSource = nullptr;
+ Hyprutils::OS::CFileDescriptor fd;
+ std::vector<SP<std::string>> events;
+ wl_event_source* eventSource = nullptr;
};
std::vector<SClient>::iterator findClientByFD(int fd);
std::vector<SClient>::iterator removeClientByFD(int fd);
private:
- int m_iSocketFD = -1;
- wl_event_source* m_pEventSource = nullptr;
+ Hyprutils::OS::CFileDescriptor m_iSocketFD;
+ wl_event_source* m_pEventSource = nullptr;
- std::vector<SClient> m_vClients;
+ std::vector<SClient> m_vClients;
};
inline UP<CEventManager> g_pEventManager;
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 2cb77d21..247550ae 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -28,7 +28,9 @@
#include <cstring>
#include <hyprutils/string/String.hpp>
+#include <hyprutils/os/FileDescriptor.hpp>
using namespace Hyprutils::String;
+using namespace Hyprutils::OS;
#include <sys/ioctl.h>
#include <fcntl.h>
@@ -853,19 +855,18 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
// vtnr is bugged for some reason.
- unsigned int ttynum = 0;
- int fd;
- if ((fd = open("/dev/tty", O_RDONLY | O_NOCTTY)) >= 0) {
+ unsigned int ttynum = 0;
+ Hyprutils::OS::CFileDescriptor fd{open("/dev/tty", O_RDONLY | O_NOCTTY)};
+ if (fd.isValid()) {
#if defined(VT_GETSTATE)
struct vt_stat st;
- if (!ioctl(fd, VT_GETSTATE, &st))
+ if (!ioctl(fd.get(), VT_GETSTATE, &st))
ttynum = st.v_active;
#elif defined(VT_GETACTIVE)
int vt;
- if (!ioctl(fd, VT_GETACTIVE, &vt))
+ if (!ioctl(fd.get(), VT_GETACTIVE, &vt))
ttynum = vt;
#endif
- close(fd);
}
if (ttynum == TTY)
@@ -944,11 +945,11 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo
Debug::log(LOG, "Unable to create pipe for fork");
}
- pid_t child, grandchild;
+ CFileDescriptor pipeSock[2] = {CFileDescriptor{socket[0]}, CFileDescriptor{socket[1]}};
+
+ pid_t child, grandchild;
child = fork();
if (child < 0) {
- close(socket[0]);
- close(socket[1]);
Debug::log(LOG, "Fail to create the first fork");
return 0;
}
@@ -967,22 +968,16 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo
setenv(e.first.c_str(), e.second.c_str(), 1);
}
setenv("WAYLAND_DISPLAY", g_pCompositor->m_szWLDisplaySocket.c_str(), 1);
- close(socket[0]);
- close(socket[1]);
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
// exit grandchild
_exit(0);
}
- close(socket[0]);
- write(socket[1], &grandchild, sizeof(grandchild));
- close(socket[1]);
+ write(pipeSock[1].get(), &grandchild, sizeof(grandchild));
// exit child
_exit(0);
}
// run in parent
- close(socket[1]);
- read(socket[0], &grandchild, sizeof(grandchild));
- close(socket[0]);
+ read(pipeSock[0].get(), &grandchild, sizeof(grandchild));
// clear child and leave grandchild to init
waitpid(child, nullptr, 0);
if (grandchild < 0) {
diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp
index 4021c171..83bdf4a0 100644
--- a/src/managers/eventLoop/EventLoopManager.cpp
+++ b/src/managers/eventLoop/EventLoopManager.cpp
@@ -11,11 +11,12 @@
#include <ctime>
#include <aquamarine/backend/Backend.hpp>
+using namespace Hyprutils::OS;
#define TIMESPEC_NSEC_PER_SEC 1000000000L
CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEventLoop) {
- m_sTimers.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ m_sTimers.timerfd = CFileDescriptor{timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC)};
m_sWayland.loop = wlEventLoop;
m_sWayland.display = display;
}
@@ -31,8 +32,6 @@ CEventLoopManager::~CEventLoopManager() {
wl_event_source_remove(m_sIdle.eventSource);
if (m_configWatcherInotifySource)
wl_event_source_remove(m_configWatcherInotifySource);
- if (m_sTimers.timerfd >= 0)
- close(m_sTimers.timerfd);
}
static int timerWrite(int fd, uint32_t mask, void* data) {
@@ -52,10 +51,10 @@ static int configWatcherWrite(int fd, uint32_t mask, void* data) {
}
void CEventLoopManager::enterLoop() {
- m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd, WL_EVENT_READABLE, timerWrite, nullptr);
+ m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd.get(), WL_EVENT_READABLE, timerWrite, nullptr);
- if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0)
- m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr);
+ if (const auto& FD = g_pConfigWatcher->getInotifyFD(); FD.isValid())
+ m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD.get(), WL_EVENT_READABLE, configWatcherWrite, nullptr);
syncPollFDs();
m_sListeners.pollFDsChanged = g_pCompositor->m_pAqBackend->events.pollFDsChanged.registerListener([this](std::any d) { syncPollFDs(); });
@@ -120,7 +119,7 @@ void CEventLoopManager::nudgeTimers() {
itimerspec ts = {.it_value = now};
- timerfd_settime(m_sTimers.timerfd, TFD_TIMER_ABSTIME, &ts, nullptr);
+ timerfd_settime(m_sTimers.timerfd.get(), TFD_TIMER_ABSTIME, &ts, nullptr);
}
void CEventLoopManager::doLater(const std::function<void()>& fn) {
diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp
index 95cc6109..ebeb2160 100644
--- a/src/managers/eventLoop/EventLoopManager.hpp
+++ b/src/managers/eventLoop/EventLoopManager.hpp
@@ -6,6 +6,7 @@
#include <thread>
#include <wayland-server.h>
#include "helpers/signal/Signal.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
#include "EventLoopTimer.hpp"
@@ -54,7 +55,7 @@ class CEventLoopManager {
struct {
std::vector<SP<CEventLoopTimer>> timers;
- int timerfd = -1;
+ Hyprutils::OS::CFileDescriptor timerfd;
} m_sTimers;
SIdleData m_sIdle;
diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp
index 6fdbaf4b..e70f0441 100644
--- a/src/protocols/DRMLease.cpp
+++ b/src/protocols/DRMLease.cpp
@@ -4,6 +4,7 @@
#include "managers/eventLoop/EventLoopManager.hpp"
#include <aquamarine/backend/DRM.hpp>
#include <fcntl.h>
+using namespace Hyprutils::OS;
CDRMLeaseResource::CDRMLeaseResource(SP<CWpDrmLeaseV1> resource_, SP<CDRMLeaseRequestResource> request) : resource(resource_) {
if UNLIKELY (!good())
@@ -185,15 +186,14 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
RESOURCE->parent = self;
});
- int fd = ((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD();
- if (fd < 0) {
+ 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)
@@ -231,16 +231,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();
+ 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;
}
diff --git a/src/protocols/DRMLease.hpp b/src/protocols/DRMLease.hpp
index ec1e73f2..c7849149 100644
--- a/src/protocols/DRMLease.hpp
+++ b/src/protocols/DRMLease.hpp
@@ -5,6 +5,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)
diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp
index ce598385..23dafbca 100644
--- a/src/protocols/DRMSyncobj.cpp
+++ b/src/protocols/DRMSyncobj.cpp
@@ -6,6 +6,7 @@
#include "../Compositor.hpp"
#include <fcntl.h>
+using namespace Hyprutils::OS;
CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP<CWpLinuxDrmSyncobjSurfaceV1> resource_, SP<CWLSurfaceResource> surface_) : surface(surface_), resource(resource_) {
if UNLIKELY (!good())
@@ -103,7 +104,7 @@ bool CDRMSyncobjSurfaceResource::good() {
return resource->resource();
}
-CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, int fd_) : fd(fd_), resource(resource_) {
+CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, CFileDescriptor fd_) : fd(std::move(fd_)), resource(resource_) {
if UNLIKELY (!good())
return;
@@ -112,7 +113,7 @@ 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");
@@ -120,11 +121,6 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTi
}
}
-CDRMSyncobjTimelineResource::~CDRMSyncobjTimelineResource() {
- if (fd >= 0)
- close(fd);
-}
-
SP<CDRMSyncobjTimelineResource> CDRMSyncobjTimelineResource::fromResource(wl_resource* res) {
auto data = (CDRMSyncobjTimelineResource*)(((CWpLinuxDrmSyncobjTimelineV1*)wl_resource_get_user_data(res))->data());
return data ? data->self.lock() : nullptr;
@@ -171,7 +167,7 @@ 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), CFileDescriptor{fd});
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
return;
diff --git a/src/protocols/DRMSyncobj.hpp b/src/protocols/DRMSyncobj.hpp
index 42ecdb3e..8677576f 100644
--- a/src/protocols/DRMSyncobj.hpp
+++ b/src/protocols/DRMSyncobj.hpp
@@ -4,6 +4,7 @@
#include "WaylandProtocol.hpp"
#include "linux-drm-syncobj-v1.hpp"
#include "../helpers/signal/Signal.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CWLSurfaceResource;
class CDRMSyncobjTimelineResource;
@@ -32,14 +33,14 @@ class CDRMSyncobjSurfaceResource {
class CDRMSyncobjTimelineResource {
public:
- CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, int fd_);
- ~CDRMSyncobjTimelineResource();
+ CDRMSyncobjTimelineResource(SP<CWpLinuxDrmSyncobjTimelineV1> resource_, Hyprutils::OS::CFileDescriptor fd_);
+ ~CDRMSyncobjTimelineResource() = default;
static SP<CDRMSyncobjTimelineResource> fromResource(wl_resource*);
bool good();
WP<CDRMSyncobjTimelineResource> self;
- int fd = -1;
+ Hyprutils::OS::CFileDescriptor fd;
SP<CSyncTimeline> timeline;
private:
diff --git a/src/protocols/DataDeviceWlr.cpp b/src/protocols/DataDeviceWlr.cpp
index 71ee1c4a..3da5afd6 100644
--- a/src/protocols/DataDeviceWlr.cpp
+++ b/src/protocols/DataDeviceWlr.cpp
@@ -2,6 +2,7 @@
#include <algorithm>
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
+using namespace Hyprutils::OS;
CWLRDataOffer::CWLRDataOffer(SP<CZwlrDataControlOfferV1> resource_, SP<IDataSource> source_) : source(source_), resource(resource_) {
if UNLIKELY (!good())
@@ -11,21 +12,20 @@ CWLRDataOffer::CWLRDataOffer(SP<CZwlrDataControlOfferV1> resource_, SP<IDataSour
resource->setOnDestroy([this](CZwlrDataControlOfferV1* r) { PROTO::dataWlr->destroyResource(this); });
resource->setReceive([this](CZwlrDataControlOfferV1* r, const char* mime, int32_t fd) {
+ CFileDescriptor sendFd{fd};
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
- close(fd);
return;
}
if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
- close(fd);
return;
}
LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get());
- source->send(mime, fd);
+ source->send(mime, std::move(sendFd));
});
}
@@ -77,15 +77,13 @@ std::vector<std::string> CWLRDataSource::mimes() {
return mimeTypes;
}
-void CWLRDataSource::send(const std::string& mime, uint32_t fd) {
+void CWLRDataSource::send(const std::string& mime, CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CWLRDataSource::sendAskSend with non-existent mime");
- close(fd);
return;
}
- resource->sendSend(mime.c_str(), fd);
- close(fd);
+ resource->sendSend(mime.c_str(), fd.get());
}
void CWLRDataSource::accepted(const std::string& mime) {
diff --git a/src/protocols/DataDeviceWlr.hpp b/src/protocols/DataDeviceWlr.hpp
index 5eef163c..7f14b320 100644
--- a/src/protocols/DataDeviceWlr.hpp
+++ b/src/protocols/DataDeviceWlr.hpp
@@ -5,6 +5,7 @@
#include "WaylandProtocol.hpp"
#include "wlr-data-control-unstable-v1.hpp"
#include "types/DataDevice.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CWLRDataControlManagerResource;
class CWLRDataSource;
@@ -38,7 +39,7 @@ class CWLRDataSource : public IDataSource {
bool good();
virtual std::vector<std::string> mimes();
- virtual void send(const std::string& mime, uint32_t fd);
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp
index 43ba9d41..0a383e2e 100644
--- a/src/protocols/GammaControl.cpp
+++ b/src/protocols/GammaControl.cpp
@@ -4,6 +4,7 @@
#include "../helpers/Monitor.hpp"
#include "../protocols/core/Output.hpp"
#include "../render/Renderer.hpp"
+using namespace Hyprutils::OS;
CGammaControl::CGammaControl(SP<CZwlrGammaControlV1> resource_, wl_resource* output) : resource(resource_) {
if UNLIKELY (!resource_->resource())
@@ -46,34 +47,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) {
+ 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");
@@ -85,7 +85,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;
diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp
index 796cec06..33121ecd 100644
--- a/src/protocols/InputMethodV2.cpp
+++ b/src/protocols/InputMethodV2.cpp
@@ -33,25 +33,22 @@ void CInputMethodKeyboardGrabV2::sendKeyboardData(SP<IKeyboard> keyboard) {
pLastKeyboard = keyboard;
- int keymapFD = allocateSHMFile(keyboard->xkbKeymapString.length() + 1);
- if UNLIKELY (keymapFD < 0) {
+ auto keymapFD = allocateSHMFile(keyboard->xkbKeymapString.length() + 1);
+ if UNLIKELY (!keymapFD.isValid()) {
LOGM(ERR, "Failed to create a keymap file for keyboard grab");
return;
}
- void* data = mmap(nullptr, keyboard->xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD, 0);
+ void* data = mmap(nullptr, keyboard->xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD.get(), 0);
if UNLIKELY (data == MAP_FAILED) {
LOGM(ERR, "Failed to mmap a keymap file for keyboard grab");
- close(keymapFD);
return;
}
memcpy(data, keyboard->xkbKeymapString.c_str(), keyboard->xkbKeymapString.length());
munmap(data, keyboard->xkbKeymapString.length() + 1);
- resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD, keyboard->xkbKeymapString.length() + 1);
-
- close(keymapFD);
+ resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD.get(), keyboard->xkbKeymapString.length() + 1);
sendMods(keyboard->modifiersState.depressed, keyboard->modifiersState.latched, keyboard->modifiersState.locked, keyboard->modifiersState.group);
diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp
index d3135da0..b7b91594 100644
--- a/src/protocols/LinuxDMABUF.cpp
+++ b/src/protocols/LinuxDMABUF.cpp
@@ -14,6 +14,8 @@
#include "../render/OpenGL.hpp"
#include "../Compositor.hpp"
+using namespace Hyprutils::OS;
+
static std::optional<dev_t> devIDFromFD(int fd) {
struct stat stat;
if (fstat(fd, &stat) != 0)
@@ -77,29 +79,21 @@ CDMABUFFormatTable::CDMABUFFormatTable(SDMABUFTranche _rendererTranche, std::vec
tableSize = formatsVec.size() * sizeof(SDMABUFFormatTableEntry);
- int fds[2] = {0};
- allocateSHMFilePair(tableSize, &fds[0], &fds[1]);
+ CFileDescriptor fds[2];
+ allocateSHMFilePair(tableSize, fds[0], fds[1]);
- auto arr = (SDMABUFFormatTableEntry*)mmap(nullptr, tableSize, PROT_READ | PROT_WRITE, MAP_SHARED, fds[0], 0);
+ auto arr = (SDMABUFFormatTableEntry*)mmap(nullptr, tableSize, PROT_READ | PROT_WRITE, MAP_SHARED, fds[0].get(), 0);
if (arr == MAP_FAILED) {
LOGM(ERR, "mmap failed");
- close(fds[0]);
- close(fds[1]);
return;
}
- close(fds[0]);
-
std::copy(formatsVec.begin(), formatsVec.end(), arr);
munmap(arr, tableSize);
- tableFD = fds[1];
-}
-
-CDMABUFFormatTable::~CDMABUFFormatTable() {
- close(tableFD);
+ tableFD = std::move(fds[1]);
}
CLinuxDMABuffer::CLinuxDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs attrs) {
@@ -234,18 +228,18 @@ void CLinuxDMABUFParamsResource::create(uint32_t id) {
}
bool CLinuxDMABUFParamsResource::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;
}
@@ -303,7 +297,7 @@ CLinuxDMABUFFeedbackResource::CLinuxDMABUFFeedbackResource(SP<CZwpLinuxDmabufFee
resource->setDestroy([this](CZwpLinuxDmabufFeedbackV1* r) { PROTO::linuxDma->destroyResource(this); });
auto& formatTable = PROTO::linuxDma->formatTable;
- resource->sendFormatTable(formatTable->tableFD, formatTable->tableSize);
+ resource->sendFormatTable(formatTable->tableFD.get(), formatTable->tableSize);
sendDefaultFeedback();
}
@@ -472,9 +466,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 = 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;
@@ -496,7 +490,7 @@ void CLinuxDMABufV1Protocol::resetFormatTable() {
auto newFormatTable = makeUnique<CDMABUFFormatTable>(formatTable->rendererTranche, formatTable->monitorTranches);
for (auto const& feedback : m_vFeedbacks) {
- feedback->resource->sendFormatTable(newFormatTable->tableFD, newFormatTable->tableSize);
+ feedback->resource->sendFormatTable(newFormatTable->tableFD.get(), newFormatTable->tableSize);
if (feedback->lastFeedbackWasScanout) {
PHLMONITOR mon;
auto HLSurface = CWLSurface::fromResource(feedback->surface);
@@ -519,11 +513,6 @@ void CLinuxDMABufV1Protocol::resetFormatTable() {
formatTable = std::move(newFormatTable);
}
-CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() {
- if (mainDeviceFD >= 0)
- close(mainDeviceFD);
-}
-
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)));
diff --git a/src/protocols/LinuxDMABUF.hpp b/src/protocols/LinuxDMABUF.hpp
index 91cf3283..6c967878 100644
--- a/src/protocols/LinuxDMABUF.hpp
+++ b/src/protocols/LinuxDMABUF.hpp
@@ -9,6 +9,7 @@
#include "../helpers/Format.hpp"
#include "../helpers/Monitor.hpp"
#include <aquamarine/buffer/Buffer.hpp>
+#include <hyprutils/os/FileDescriptor.hpp>
class CDMABuffer;
class CWLSurfaceResource;
@@ -48,9 +49,9 @@ struct SDMABUFTranche {
class CDMABUFFormatTable {
public:
CDMABUFFormatTable(SDMABUFTranche rendererTranche, std::vector<std::pair<PHLMONITORREF, SDMABUFTranche>> tranches);
- ~CDMABUFFormatTable();
+ ~CDMABUFFormatTable() = default;
- int tableFD = -1;
+ Hyprutils::OS::CFileDescriptor tableFD;
size_t tableSize = 0;
SDMABUFTranche rendererTranche;
std::vector<std::pair<PHLMONITORREF, SDMABUFTranche>> monitorTranches;
@@ -107,7 +108,7 @@ class CLinuxDMABUFResource {
class CLinuxDMABufV1Protocol : public IWaylandProtocol {
public:
CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name);
- ~CLinuxDMABufV1Protocol();
+ ~CLinuxDMABufV1Protocol() = default;
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
void updateScanoutTranche(SP<CWLSurfaceResource> surface, PHLMONITOR pMonitor);
@@ -128,7 +129,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol {
UP<CDMABUFFormatTable> formatTable;
dev_t mainDevice;
- int mainDeviceFD = -1;
+ Hyprutils::OS::CFileDescriptor mainDeviceFD;
friend class CLinuxDMABUFResource;
friend class CLinuxDMABUFFeedbackResource;
diff --git a/src/protocols/PrimarySelection.cpp b/src/protocols/PrimarySelection.cpp
index 567bfdd2..620f262e 100644
--- a/src/protocols/PrimarySelection.cpp
+++ b/src/protocols/PrimarySelection.cpp
@@ -3,6 +3,7 @@
#include "../managers/SeatManager.hpp"
#include "core/Seat.hpp"
#include "../config/ConfigValue.hpp"
+using namespace Hyprutils::OS;
CPrimarySelectionOffer::CPrimarySelectionOffer(SP<CZwpPrimarySelectionOfferV1> resource_, SP<IDataSource> source_) : source(source_), resource(resource_) {
if UNLIKELY (!good())
@@ -12,21 +13,20 @@ CPrimarySelectionOffer::CPrimarySelectionOffer(SP<CZwpPrimarySelectionOfferV1> r
resource->setOnDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setReceive([this](CZwpPrimarySelectionOfferV1* r, const char* mime, int32_t fd) {
+ CFileDescriptor sendFd{fd};
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
- close(fd);
return;
}
if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
- close(fd);
return;
}
LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get());
- source->send(mime, fd);
+ source->send(mime, std::move(sendFd));
});
}
@@ -78,15 +78,13 @@ std::vector<std::string> CPrimarySelectionSource::mimes() {
return mimeTypes;
}
-void CPrimarySelectionSource::send(const std::string& mime, uint32_t fd) {
+void CPrimarySelectionSource::send(const std::string& mime, CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CPrimarySelectionSource::sendAskSend with non-existent mime");
- close(fd);
return;
}
- resource->sendSend(mime.c_str(), fd);
- close(fd);
+ resource->sendSend(mime.c_str(), fd.get());
}
void CPrimarySelectionSource::accepted(const std::string& mime) {
diff --git a/src/protocols/PrimarySelection.hpp b/src/protocols/PrimarySelection.hpp
index aeebe03c..0ecc962b 100644
--- a/src/protocols/PrimarySelection.hpp
+++ b/src/protocols/PrimarySelection.hpp
@@ -5,6 +5,7 @@
#include "WaylandProtocol.hpp"
#include "primary-selection-unstable-v1.hpp"
#include "types/DataDevice.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CPrimarySelectionOffer;
class CPrimarySelectionSource;
@@ -38,7 +39,7 @@ class CPrimarySelectionSource : public IDataSource {
bool good();
virtual std::vector<std::string> mimes();
- virtual void send(const std::string& mime, uint32_t fd);
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
diff --git a/src/protocols/SecurityContext.cpp b/src/protocols/SecurityContext.cpp
index e5b3cf2a..30fca260 100644
--- a/src/protocols/SecurityContext.cpp
+++ b/src/protocols/SecurityContext.cpp
@@ -1,6 +1,7 @@
#include "SecurityContext.hpp"
#include "../Compositor.hpp"
#include <sys/socket.h>
+using namespace Hyprutils::OS;
static int onListenFdEvent(int fd, uint32_t mask, void* data) {
auto sc = (CSecurityContext*)data;
@@ -14,8 +15,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(CFileDescriptor clientFD_) {
+ auto p = SP<CSecurityContextSandboxedClient>(new CSecurityContextSandboxedClient(std::move(clientFD_)));
if (!p->client)
return nullptr;
return p;
@@ -27,8 +28,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(CFileDescriptor clientFD_) : clientFD(std::move(clientFD_)) {
+ client = wl_client_create(g_pCompositor->m_sWLDisplay, clientFD.get());
if (!client)
return;
@@ -41,7 +42,6 @@ CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_)
CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() {
wl_list_remove(&destroyListener.listener.link);
wl_list_init(&destroyListener.listener.link);
- close(clientFD);
}
void CSecurityContextSandboxedClient::onDestroy() {
@@ -113,8 +113,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();
@@ -144,16 +144,15 @@ void CSecurityContext::onListen(uint32_t mask) {
if (!(mask & WL_EVENT_READABLE))
return;
- int clientFD = accept(listenFD, nullptr, nullptr);
- if UNLIKELY (clientFD < 0) {
+ 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;
}
diff --git a/src/protocols/SecurityContext.hpp b/src/protocols/SecurityContext.hpp
index 2bec08d4..56d4f7b4 100644
--- a/src/protocols/SecurityContext.hpp
+++ b/src/protocols/SecurityContext.hpp
@@ -4,19 +4,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;
@@ -44,7 +45,7 @@ struct SCSecurityContextSandboxedClientDestroyWrapper {
class CSecurityContextSandboxedClient {
public:
- static SP<CSecurityContextSandboxedClient> create(int clientFD);
+ static SP<CSecurityContextSandboxedClient> create(Hyprutils::OS::CFileDescriptor clientFD);
~CSecurityContextSandboxedClient();
void onDestroy();
@@ -52,10 +53,10 @@ class CSecurityContextSandboxedClient {
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;
diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp
index 4fec57c0..00aca041 100644
--- a/src/protocols/VirtualKeyboard.cpp
+++ b/src/protocols/VirtualKeyboard.cpp
@@ -1,6 +1,7 @@
#include "VirtualKeyboard.hpp"
#include <sys/mman.h>
#include "../devices/IKeyboard.hpp"
+using namespace Hyprutils::OS;
CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
if UNLIKELY (!good())
@@ -51,20 +52,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);
+ 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;
}
@@ -75,7 +75,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1>
LOGM(ERR, "xkbKeymap creation failed");
xkb_context_unref(xkbContext);
r->noMemory();
- close(fd);
return;
}
@@ -86,7 +85,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1>
xkb_keymap_unref(xkbKeymap);
xkb_context_unref(xkbContext);
- close(fd);
});
name = "hl-virtual-keyboard";
diff --git a/src/protocols/VirtualKeyboard.hpp b/src/protocols/VirtualKeyboard.hpp
index 8157b276..0a13003b 100644
--- a/src/protocols/VirtualKeyboard.hpp
+++ b/src/protocols/VirtualKeyboard.hpp
@@ -5,6 +5,7 @@
#include "WaylandProtocol.hpp"
#include "virtual-keyboard-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CVirtualKeyboardV1Resource {
public:
diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp
index e17b5612..0931608a 100644
--- a/src/protocols/core/DataDevice.cpp
+++ b/src/protocols/core/DataDevice.cpp
@@ -13,6 +13,7 @@
#include "../../managers/HookSystemManager.hpp"
#include "../../helpers/Monitor.hpp"
#include "../../render/Renderer.hpp"
+using namespace Hyprutils::OS;
CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataSource> source_) : source(source_), resource(resource_) {
if UNLIKELY (!good())
@@ -39,15 +40,14 @@ CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataS
});
resource->setReceive([this](CWlDataOffer* r, const char* mime, uint32_t fd) {
+ CFileDescriptor sendFd{fd};
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
- close(fd);
return;
}
if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
- close(fd);
return;
}
@@ -58,7 +58,7 @@ CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataS
source->accepted(mime ? mime : "");
}
- source->send(mime ? mime : "", fd);
+ source->send(mime ? mime : "", std::move(sendFd));
recvd = true;
@@ -182,15 +182,13 @@ std::vector<std::string> CWLDataSourceResource::mimes() {
return mimeTypes;
}
-void CWLDataSourceResource::send(const std::string& mime, uint32_t fd) {
+void CWLDataSourceResource::send(const std::string& mime, CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CWLDataSourceResource::sendAskSend with non-existent mime");
- close(fd);
return;
}
- resource->sendSend(mime.c_str(), fd);
- close(fd);
+ resource->sendSend(mime.c_str(), fd.get());
}
void CWLDataSourceResource::cancelled() {
diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp
index d8bc2b9c..dfea4a71 100644
--- a/src/protocols/core/DataDevice.hpp
+++ b/src/protocols/core/DataDevice.hpp
@@ -16,6 +16,7 @@
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../types/DataDevice.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CWLDataDeviceResource;
class CWLDataDeviceManagerResource;
@@ -63,7 +64,7 @@ class CWLDataSourceResource : public IDataSource {
bool good();
virtual std::vector<std::string> mimes();
- virtual void send(const std::string& mime, uint32_t fd);
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual bool hasDnd();
diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp
index c6b2de05..1f07a15e 100644
--- a/src/protocols/core/Seat.cpp
+++ b/src/protocols/core/Seat.cpp
@@ -321,35 +321,18 @@ void CWLKeyboardResource::sendKeymap(SP<IKeyboard> keyboard) {
if (!(PROTO::seat->currentCaps & eHIDCapabilityType::HID_INPUT_CAPABILITY_KEYBOARD))
return;
- std::string_view keymap;
- int fd;
- uint32_t size;
- if (keyboard) {
- keymap = keyboard->xkbKeymapString;
- fd = keyboard->xkbKeymapFD;
- size = keyboard->xkbKeymapString.length() + 1;
- } else {
- fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- LOGM(ERR, "Failed to open /dev/null");
- return;
- }
- size = 0;
- }
+ std::string_view keymap = keyboard->xkbKeymapString;
+ Hyprutils::OS::CFileDescriptor& fd = keyboard->xkbKeymapFD;
+ uint32_t size = keyboard->xkbKeymapString.length() + 1;
- if (keymap == lastKeymap) {
- if (!keyboard)
- close(fd);
+ if (keymap == lastKeymap)
return;
- }
+
lastKeymap = keymap;
const wl_keyboard_keymap_format format = keyboard ? WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 : WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP;
- resource->sendKeymap(format, fd, size);
-
- if (!keyboard)
- close(fd);
+ resource->sendKeymap(format, fd.get(), size);
}
void CWLKeyboardResource::sendEnter(SP<CWLSurfaceResource> surface) {
diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp
index 1649f82f..e0e62560 100644
--- a/src/protocols/core/Shm.cpp
+++ b/src/protocols/core/Shm.cpp
@@ -7,6 +7,7 @@
#include "../types/WLBuffer.hpp"
#include "../../helpers/Format.hpp"
#include "../../render/Renderer.hpp"
+using namespace Hyprutils::OS;
CWLSHMBuffer::CWLSHMBuffer(SP<CWLSHMPoolResource> pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) {
if UNLIKELY (!pool_->pool->data)
@@ -51,7 +52,7 @@ bool CWLSHMBuffer::isSynchronous() {
Aquamarine::SSHMAttrs CWLSHMBuffer::shm() {
Aquamarine::SSHMAttrs attrs;
attrs.success = true;
- attrs.fd = pool->fd;
+ attrs.fd = pool->fd.get();
attrs.format = NFormatUtils::shmToDRM(fmt);
attrs.size = size;
attrs.stride = stride;
@@ -75,13 +76,12 @@ void CWLSHMBuffer::update(const CRegion& damage) {
texture->update(NFormatUtils::shmToDRM(fmt), (uint8_t*)pool->data + offset, stride, damage);
}
-CSHMPool::CSHMPool(int fd_, size_t size_) : fd(fd_), size(size_), data(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) {
+CSHMPool::CSHMPool(CFileDescriptor fd_, size_t size_) : fd(std::move(fd_)), size(size_), data(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0)) {
;
}
CSHMPool::~CSHMPool() {
munmap(data, size);
- close(fd);
}
void CSHMPool::resize(size_t size_) {
@@ -90,23 +90,23 @@ void CSHMPool::resize(size_t size_) {
if (data)
munmap(data, size);
size = size_;
- data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
if UNLIKELY (data == MAP_FAILED)
- LOGM(ERR, "Couldn't mmap {} bytes from fd {} of shm client", size, fd);
+ LOGM(ERR, "Couldn't mmap {} bytes from fd {} of shm client", size, fd.get());
}
-static int shmIsSizeValid(int fd, size_t size) {
+static int shmIsSizeValid(CFileDescriptor& fd, size_t size) {
struct stat st;
- if UNLIKELY (fstat(fd, &st) == -1) {
- LOGM(ERR, "Couldn't get stat for fd {} of shm client", fd);
+ if UNLIKELY (fstat(fd.get(), &st) == -1) {
+ LOGM(ERR, "Couldn't get stat for fd {} of shm client", fd.get());
return 0;
}
return (size_t)st.st_size >= size;
}
-CWLSHMPoolResource::CWLSHMPoolResource(SP<CWlShmPool> resource_, int fd_, size_t size_) : resource(resource_) {
+CWLSHMPoolResource::CWLSHMPoolResource(SP<CWlShmPool> resource_, CFileDescriptor fd_, size_t size_) : resource(resource_) {
if UNLIKELY (!good())
return;
@@ -115,7 +115,7 @@ CWLSHMPoolResource::CWLSHMPoolResource(SP<CWlShmPool> resource_, int fd_, size_t
return;
}
- pool = makeShared<CSHMPool>(fd_, size_);
+ pool = makeShared<CSHMPool>(std::move(fd_), size_);
resource->setDestroy([this](CWlShmPool* r) { PROTO::shm->destroyResource(this); });
resource->setOnDestroy([this](CWlShmPool* r) { PROTO::shm->destroyResource(this); });
@@ -176,7 +176,8 @@ CWLSHMResource::CWLSHMResource(SP<CWlShm> resource_) : resource(resource_) {
resource->setOnDestroy([this](CWlShm* r) { PROTO::shm->destroyResource(this); });
resource->setCreatePool([](CWlShm* r, uint32_t id, int32_t fd, int32_t size) {
- const auto RESOURCE = PROTO::shm->m_vPools.emplace_back(makeShared<CWLSHMPoolResource>(makeShared<CWlShmPool>(r->client(), r->version(), id), fd, size));
+ CFileDescriptor poolFd{fd};
+ const auto RESOURCE = PROTO::shm->m_vPools.emplace_back(makeShared<CWLSHMPoolResource>(makeShared<CWlShmPool>(r->client(), r->version(), id), std::move(poolFd), size));
if UNLIKELY (!RESOURCE->good()) {
r->noMemory();
diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp
index d7e81367..fef821cb 100644
--- a/src/protocols/core/Shm.hpp
+++ b/src/protocols/core/Shm.hpp
@@ -7,6 +7,8 @@
- wl_buffer with shm
*/
+#include <hyprutils/os/FileDescriptor.hpp>
+#include <memory>
#include <vector>
#include <cstdint>
#include "../WaylandProtocol.hpp"
@@ -18,14 +20,14 @@ class CWLSHMPoolResource;
class CSHMPool {
public:
- CSHMPool(int fd, size_t size);
+ CSHMPool(Hyprutils::OS::CFileDescriptor fd, size_t size);
~CSHMPool();
- int fd = 0;
- size_t size = 0;
- void* data = nullptr;
+ Hyprutils::OS::CFileDescriptor fd;
+ size_t size = 0;
+ void* data = nullptr;
- void resize(size_t size);
+ void resize(size_t size);
};
class CWLSHMBuffer : public IHLBuffer {
@@ -57,7 +59,7 @@ class CWLSHMBuffer : public IHLBuffer {
class CWLSHMPoolResource {
public:
- CWLSHMPoolResource(SP<CWlShmPool> resource_, int fd, size_t size);
+ CWLSHMPoolResource(SP<CWlShmPool> resource_, Hyprutils::OS::CFileDescriptor fd, size_t size);
bool good();
diff --git a/src/protocols/types/DataDevice.hpp b/src/protocols/types/DataDevice.hpp
index 62f10de2..cbb4b271 100644
--- a/src/protocols/types/DataDevice.hpp
+++ b/src/protocols/types/DataDevice.hpp
@@ -7,6 +7,7 @@
#include <wayland-server-protocol.h>
#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/math/Math.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
class CWLDataOfferResource;
class CX11DataOffer;
@@ -24,10 +25,10 @@ class IDataSource {
IDataSource() = default;
virtual ~IDataSource() = default;
- virtual std::vector<std::string> mimes() = 0;
- virtual void send(const std::string& mime, uint32_t fd) = 0;
- virtual void accepted(const std::string& mime) = 0;
- virtual void cancelled() = 0;
+ virtual std::vector<std::string> mimes() = 0;
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) = 0;
+ virtual void accepted(const std::string& mime) = 0;
+ virtual void cancelled() = 0;
virtual bool hasDnd();
virtual bool dndDone();
virtual void sendDndFinished();
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 78b53c9b..e4aadd63 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -19,6 +19,7 @@
#include <fcntl.h>
#include <gbm.h>
#include <filesystem>
+using namespace Hyprutils::OS;
const std::vector<const char*> ASSET_PATHS = {
#ifdef DATAROOTDIR
@@ -301,11 +302,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_iDRMFD(g_pCompositor->m_iDRMFD) {
Debug::log(WARN, "EGL: EXT_platform_device or EGL_EXT_device_query not supported, using gbm");
if (EGLEXTENSIONS.contains("KHR_platform_gbm")) {
success = true;
- m_iGBMFD = openRenderNode(m_iDRMFD);
- if (m_iGBMFD < 0)
+ m_iGBMFD = CFileDescriptor{openRenderNode(m_iDRMFD)};
+ if (!m_iGBMFD.isValid())
RASSERT(false, "Couldn't open a gbm fd");
- m_pGbmDevice = gbm_create_device(m_iGBMFD);
+ m_pGbmDevice = gbm_create_device(m_iGBMFD.get());
if (!m_pGbmDevice)
RASSERT(false, "Couldn't open a gbm device");
@@ -371,9 +372,6 @@ CHyprOpenGLImpl::~CHyprOpenGLImpl() {
if (m_pGbmDevice)
gbm_device_destroy(m_pGbmDevice);
-
- if (m_iGBMFD >= 0)
- close(m_iGBMFD);
}
std::optional<std::vector<uint64_t>> CHyprOpenGLImpl::getModsForFormat(EGLint format) {
@@ -2954,29 +2952,28 @@ std::vector<SDRMFormat> CHyprOpenGLImpl::getDRMFormats() {
return drmFormats;
}
-SP<CEGLSync> CHyprOpenGLImpl::createEGLSync(int fenceFD) {
+SP<CEGLSync> CHyprOpenGLImpl::createEGLSync(CFileDescriptor fenceFD) {
std::vector<EGLint> attribs;
- int dupFd = -1;
- if (fenceFD > 0) {
- dupFd = fcntl(fenceFD, F_DUPFD_CLOEXEC, 0);
- if (dupFd < 0) {
+ CFileDescriptor dupFd;
+ if (fenceFD.isValid()) {
+ dupFd = fenceFD.duplicate();
+ if (!dupFd.isValid()) {
Debug::log(ERR, "createEGLSync: dup failed");
return nullptr;
}
// reserve number of elements to avoid reallocations
attribs.reserve(3);
attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
- attribs.push_back(dupFd);
+ attribs.push_back(dupFd.get());
attribs.push_back(EGL_NONE);
}
EGLSyncKHR sync = m_sProc.eglCreateSyncKHR(m_pEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data());
if (sync == EGL_NO_SYNC_KHR) {
Debug::log(ERR, "eglCreateSyncKHR failed");
- if (dupFd >= 0)
- close(dupFd);
return nullptr;
- }
+ } else
+ dupFd.take(); // eglCreateSyncKHR only takes ownership on success
// we need to flush otherwise we might not get a valid fd
glFlush();
@@ -2989,19 +2986,18 @@ SP<CEGLSync> CHyprOpenGLImpl::createEGLSync(int fenceFD) {
auto eglsync = SP<CEGLSync>(new CEGLSync);
eglsync->sync = sync;
- eglsync->m_iFd = fd;
+ eglsync->m_iFd = CFileDescriptor{fd};
return eglsync;
}
bool CHyprOpenGLImpl::waitForTimelinePoint(SP<CSyncTimeline> timeline, uint64_t point) {
- int fd = timeline->exportAsSyncFileFD(point);
- if (fd < 0) {
+ auto fd = timeline->exportAsSyncFileFD(point);
+ if (!fd.isValid()) {
Debug::log(ERR, "waitForTimelinePoint: failed to get a fd from explicit timeline");
return false;
}
- auto sync = g_pHyprOpenGL->createEGLSync(fd);
- close(fd);
+ auto sync = g_pHyprOpenGL->createEGLSync(std::move(fd));
if (!sync) {
Debug::log(ERR, "waitForTimelinePoint: failed to get an eglsync from explicit timeline");
return false;
@@ -3082,12 +3078,9 @@ CEGLSync::~CEGLSync() {
if (g_pHyprOpenGL->m_sProc.eglDestroySyncKHR(g_pHyprOpenGL->m_pEglDisplay, sync) != EGL_TRUE)
Debug::log(ERR, "eglDestroySyncKHR failed");
-
- if (m_iFd >= 0)
- close(m_iFd);
}
-int CEGLSync::fd() {
+CFileDescriptor& CEGLSync::fd() {
return m_iFd;
}
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 1ebb0162..d7abdf63 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -24,6 +24,7 @@
#include <EGL/eglext.h>
#include <GLES2/gl2ext.h>
#include <aquamarine/buffer/Buffer.hpp>
+#include <hyprutils/os/FileDescriptor.hpp>
#include "../debug/TracyDefines.hpp"
@@ -146,15 +147,15 @@ class CEGLSync {
public:
~CEGLSync();
- EGLSyncKHR sync = nullptr;
+ EGLSyncKHR sync = nullptr;
- int fd();
- bool wait();
+ Hyprutils::OS::CFileDescriptor& fd();
+ bool wait();
private:
CEGLSync() = default;
- int m_iFd = -1;
+ Hyprutils::OS::CFileDescriptor m_iFd;
friend class CHyprOpenGLImpl;
};
@@ -228,14 +229,14 @@ class CHyprOpenGLImpl {
uint32_t getPreferredReadFormat(PHLMONITOR pMonitor);
std::vector<SDRMFormat> getDRMFormats();
EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
- SP<CEGLSync> createEGLSync(int fenceFD);
+ SP<CEGLSync> createEGLSync(Hyprutils::OS::CFileDescriptor fenceFD);
bool waitForTimelinePoint(SP<CSyncTimeline> timeline, uint64_t point);
SCurrentRenderData m_RenderData;
GLint m_iCurrentOutputFb = 0;
- int m_iGBMFD = -1;
+ Hyprutils::OS::CFileDescriptor m_iGBMFD;
gbm_device* m_pGbmDevice = nullptr;
EGLContext m_pEglContext = nullptr;
EGLDisplay m_pEglDisplay = nullptr;
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 67d8b58b..42445728 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -36,6 +36,7 @@
#include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::Utils;
+using namespace Hyprutils::OS;
extern "C" {
#include <xf86drm.h>
@@ -1462,10 +1463,10 @@ static hdr_output_metadata createHDRMetadata(SImageDescription settings, Aquamar
bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
// apply timelines for explicit sync
// save inFD otherwise reset will reset it
- auto inFD = pMonitor->output->state->state().explicitInFence;
+ CFileDescriptor inFD{pMonitor->output->state->state().explicitInFence};
pMonitor->output->state->resetExplicitFences();
- if (inFD >= 0)
- pMonitor->output->state->setExplicitInFence(inFD);
+ if (inFD.isValid())
+ pMonitor->output->state->setExplicitInFence(inFD.get());
static auto PHDR = CConfigValue<Hyprlang::INT>("experimental:hdr");
@@ -1515,7 +1516,7 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
bool ok = pMonitor->state.commit();
if (!ok) {
- if (inFD >= 0) {
+ if (inFD.isValid()) {
Debug::log(TRACE, "Monitor state commit failed, retrying without a fence");
pMonitor->output->state->resetExplicitFences();
ok = pMonitor->state.commit();
@@ -1534,11 +1535,8 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
if (!explicitOptions.explicitEnabled)
return ok;
- if (inFD >= 0)
- close(inFD);
-
Debug::log(TRACE, "Explicit: {} presented", explicitPresented.size());
- auto sync = g_pHyprOpenGL->createEGLSync(-1);
+ auto sync = g_pHyprOpenGL->createEGLSync({});
if (!sync)
Debug::log(TRACE, "Explicit: can't add sync, EGLSync failed");
@@ -2272,7 +2270,7 @@ void CHyprRenderer::endRender() {
auto explicitOptions = getExplicitSyncSettings();
if (PMONITOR->inTimeline && explicitOptions.explicitEnabled && explicitOptions.explicitKMSEnabled) {
- auto sync = g_pHyprOpenGL->createEGLSync(-1);
+ auto sync = g_pHyprOpenGL->createEGLSync({});
if (!sync) {
Debug::log(ERR, "renderer: couldn't create an EGLSync for out in endRender");
return;
@@ -2285,12 +2283,12 @@ void CHyprRenderer::endRender() {
}
auto fd = PMONITOR->inTimeline->exportAsSyncFileFD(PMONITOR->commitSeq);
- if (fd <= 0) {
+ if (!fd.isValid()) {
Debug::log(ERR, "renderer: couldn't export from sync timeline in endRender");
return;
}
- PMONITOR->output->state->setExplicitInFence(fd);
+ PMONITOR->output->state->setExplicitInFence(fd.take());
} else {
if (isNvidia() && *PNVIDIAANTIFLICKER)
glFinish();
diff --git a/src/xwayland/Dnd.cpp b/src/xwayland/Dnd.cpp
index d4ae3780..16d166ce 100644
--- a/src/xwayland/Dnd.cpp
+++ b/src/xwayland/Dnd.cpp
@@ -7,6 +7,8 @@
#include "../managers/XWaylandManager.hpp"
#include "../desktop/WLSurface.hpp"
+using namespace Hyprutils::OS;
+
#ifndef NO_XWAYLAND
static xcb_atom_t dndActionToAtom(uint32_t actions) {
if (actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
@@ -172,7 +174,7 @@ std::vector<std::string> CX11DataSource::mimes() {
return mimeTypes;
}
-void CX11DataSource::send(const std::string& mime, uint32_t fd) {
+void CX11DataSource::send(const std::string& mime, CFileDescriptor fd) {
;
}
diff --git a/src/xwayland/Dnd.hpp b/src/xwayland/Dnd.hpp
index 8da60ddd..fb030796 100644
--- a/src/xwayland/Dnd.hpp
+++ b/src/xwayland/Dnd.hpp
@@ -2,6 +2,7 @@
#include "../protocols/types/DataDevice.hpp"
#include <wayland-server-protocol.h>
+#include <hyprutils/os/FileDescriptor.hpp>
#define XDND_VERSION 5
@@ -35,7 +36,7 @@ class CX11DataSource : public IDataSource {
~CX11DataSource() = default;
virtual std::vector<std::string> mimes();
- virtual void send(const std::string& mime, uint32_t fd);
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual bool hasDnd();
diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp
index d5dce333..99bcdf62 100644
--- a/src/xwayland/Server.cpp
+++ b/src/xwayland/Server.cpp
@@ -24,70 +24,41 @@
#include "../defines.hpp"
#include "../Compositor.hpp"
#include "../managers/CursorManager.hpp"
+using namespace Hyprutils::OS;
// Constants
-constexpr int SOCKET_DIR_PERMISSIONS = 0755;
-constexpr int SOCKET_BACKLOG = 1;
-constexpr int MAX_SOCKET_RETRIES = 32;
-constexpr int LOCK_FILE_MODE = 0444;
-
-static bool setCloseOnExec(int fd, bool cloexec) {
- int flags = fcntl(fd, F_GETFD);
- if (flags == -1) {
- Debug::log(ERR, "fcntl failed");
- return false;
- }
-
- if (cloexec)
- flags = flags | FD_CLOEXEC;
- else
- flags = flags & ~FD_CLOEXEC;
-
- if (fcntl(fd, F_SETFD, flags) == -1) {
- Debug::log(ERR, "fcntl failed");
- return false;
- }
-
- return true;
-}
-
-static void cleanUpSocket(int fd, const char* path) {
- close(fd);
- if (path[0])
- unlink(path);
-}
-
-static inline void closeSocketSafely(int& fd) {
- if (fd >= 0)
- close(fd);
-}
-
-static int createSocket(struct sockaddr_un* addr, size_t path_size) {
- socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1;
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
+constexpr int SOCKET_DIR_PERMISSIONS = 0755;
+constexpr int SOCKET_BACKLOG = 1;
+constexpr int MAX_SOCKET_RETRIES = 32;
+constexpr int LOCK_FILE_MODE = 0444;
+
+static CFileDescriptor createSocket(struct sockaddr_un* addr, size_t path_size) {
+ socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1;
+ CFileDescriptor fd{socket(AF_UNIX, SOCK_STREAM, 0)};
+ if (!fd.isValid()) {
Debug::log(ERR, "Failed to create socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
- return -1;
+ return {};
}
- if (!setCloseOnExec(fd, true)) {
- close(fd);
- return -1;
+ if (!fd.setFlags(fd.getFlags() | FD_CLOEXEC)) {
+ return {};
}
if (addr->sun_path[0])
unlink(addr->sun_path);
- if (bind(fd, (struct sockaddr*)addr, size) < 0) {
+ if (bind(fd.get(), (struct sockaddr*)addr, size) < 0) {
Debug::log(ERR, "Failed to bind socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
- cleanUpSocket(fd, addr->sun_path);
- return -1;
+ if (addr->sun_path[0])
+ unlink(addr->sun_path);
+ return {};
}
- if (listen(fd, SOCKET_BACKLOG) < 0) {
+ if (listen(fd.get(), SOCKET_BACKLOG) < 0) {
Debug::log(ERR, "Failed to listen to socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
- cleanUpSocket(fd, addr->sun_path);
- return -1;
+ if (addr->sun_path[0])
+ unlink(addr->sun_path);
+ return {};
}
return fd;
@@ -141,7 +112,7 @@ static std::string getSocketPath(int display, bool isLinux) {
return std::format("/tmp/.X11-unix/X{}_", display);
}
-static bool openSockets(std::array<int, 2>& sockets, int display) {
+static bool openSockets(std::array<CFileDescriptor, 2>& sockets, int display) {
if (!ensureSocketDirExists())
return false;
@@ -151,17 +122,16 @@ static bool openSockets(std::array<int, 2>& sockets, int display) {
path = getSocketPath(display, false);
strncpy(addr.sun_path, path.c_str(), path.length() + 1);
- sockets[0] = createSocket(&addr, path.length());
- if (sockets[0] < 0)
+ sockets[0] = CFileDescriptor{createSocket(&addr, path.length())};
+ if (!sockets[0].isValid())
return false;
path = getSocketPath(display, true);
strncpy(addr.sun_path, path.c_str(), path.length() + 1);
- sockets[1] = createSocket(&addr, path.length());
- if (sockets[1] < 0) {
- close(sockets[0]);
- sockets[0] = -1;
+ sockets[1] = CFileDescriptor{createSocket(&addr, path.length())};
+ if (!sockets[1].isValid()) {
+ sockets[0].reset();
return false;
}
@@ -174,7 +144,8 @@ static void startServer(void* data) {
}
static int xwaylandReady(int fd, uint32_t mask, void* data) {
- return g_pXWayland->pServer->ready(fd, mask);
+ CFileDescriptor xwlFd{fd};
+ return g_pXWayland->pServer->ready(std::move(xwlFd), mask);
}
static bool safeRemove(const std::string& path) {
@@ -186,38 +157,34 @@ static bool safeRemove(const std::string& path) {
bool CXWaylandServer::tryOpenSockets() {
for (size_t i = 0; i <= MAX_SOCKET_RETRIES; ++i) {
- std::string lockPath = std::format("/tmp/.X{}-lock", i);
+ std::string lockPath = std::format("/tmp/.X{}-lock", i);
- int fd = open(lockPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, LOCK_FILE_MODE);
- if (fd >= 0) {
+ CFileDescriptor fd{open(lockPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, LOCK_FILE_MODE)};
+ if (fd.isValid()) {
// we managed to open the lock
if (!openSockets(xFDs, i)) {
safeRemove(lockPath);
- close(fd);
continue;
}
const std::string pidStr = std::to_string(getpid());
- if (write(fd, pidStr.c_str(), pidStr.length()) != (long)pidStr.length()) {
+ if (write(fd.get(), pidStr.c_str(), pidStr.length()) != (long)pidStr.length()) {
safeRemove(lockPath);
- close(fd);
continue;
}
- close(fd);
display = i;
displayName = std::format(":{}", display);
break;
}
- fd = open(lockPath.c_str(), O_RDONLY | O_CLOEXEC);
+ fd = CFileDescriptor{open(lockPath.c_str(), O_RDONLY | O_CLOEXEC)};
- if (fd < 0)
+ if (!fd.isValid())
continue;
char pidstr[12] = {0};
- read(fd, pidstr, sizeof(pidstr) - 1);
- close(fd);
+ read(fd.get(), pidstr, sizeof(pidstr) - 1);
int32_t pid = 0;
try {
@@ -249,9 +216,6 @@ CXWaylandServer::~CXWaylandServer() {
if (display < 0)
return;
- closeSocketSafely(xFDs[0]);
- closeSocketSafely(xFDs[1]);
-
std::string lockPath = std::format("/tmp/.X{}-lock", display);
safeRemove(lockPath);
@@ -277,21 +241,11 @@ void CXWaylandServer::die() {
if (pipeSource)
wl_event_source_remove(pipeSource);
- if (pipeFd >= 0)
- close(pipeFd);
-
- closeSocketSafely(waylandFDs[0]);
- closeSocketSafely(waylandFDs[1]);
- closeSocketSafely(xwmFDs[0]);
- closeSocketSafely(xwmFDs[1]);
-
// possible crash. Better to leak a bit.
//if (xwaylandClient)
// wl_client_destroy(xwaylandClient);
xwaylandClient = nullptr;
- waylandFDs = {-1, -1};
- xwmFDs = {-1, -1};
}
bool CXWaylandServer::create() {
@@ -307,15 +261,17 @@ bool CXWaylandServer::create() {
return true;
}
-void CXWaylandServer::runXWayland(int notifyFD) {
- if (!setCloseOnExec(xFDs[0], false) || !setCloseOnExec(xFDs[1], false) || !setCloseOnExec(waylandFDs[1], false) || !setCloseOnExec(xwmFDs[1], false)) {
+void CXWaylandServer::runXWayland(CFileDescriptor& notifyFD) {
+ if (!xFDs[0].setFlags(xFDs[0].getFlags() & ~FD_CLOEXEC) || !xFDs[1].setFlags(xFDs[1].getFlags() & ~FD_CLOEXEC) ||
+ !waylandFDs[1].setFlags(waylandFDs[1].getFlags() & ~FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() & ~FD_CLOEXEC)) {
Debug::log(ERR, "Failed to unset cloexec on fds");
_exit(EXIT_FAILURE);
}
- auto cmd = std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", displayName, xFDs[0], xFDs[1], notifyFD, xwmFDs[1]);
+ auto cmd =
+ std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", displayName, xFDs[0].get(), xFDs[1].get(), notifyFD.get(), xwmFDs[1].get());
- auto waylandSocket = std::format("{}", waylandFDs[1]);
+ auto waylandSocket = std::format("{}", waylandFDs[1].get());
setenv("WAYLAND_SOCKET", waylandSocket.c_str(), true);
Debug::log(LOG, "Starting XWayland with \"{}\", bon voyage!", cmd);
@@ -327,40 +283,46 @@ void CXWaylandServer::runXWayland(int notifyFD) {
}
bool CXWaylandServer::start() {
- idleSource = nullptr;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, waylandFDs.data()) != 0) {
+ idleSource = nullptr;
+ int wlPair[2] = {-1, -1};
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, wlPair) != 0) {
Debug::log(ERR, "socketpair failed (1)");
die();
return false;
}
+ waylandFDs[0] = CFileDescriptor{wlPair[0]};
+ waylandFDs[1] = CFileDescriptor{wlPair[1]};
- if (!setCloseOnExec(waylandFDs[0], true) || !setCloseOnExec(waylandFDs[1], true)) {
+ if (!waylandFDs[0].setFlags(waylandFDs[0].getFlags() | FD_CLOEXEC) || !waylandFDs[1].setFlags(waylandFDs[1].getFlags() | FD_CLOEXEC)) {
Debug::log(ERR, "set_cloexec failed (1)");
die();
return false;
}
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, xwmFDs.data()) != 0) {
+ int xwmPair[2] = {-1, -1};
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, xwmPair) != 0) {
Debug::log(ERR, "socketpair failed (2)");
die();
return false;
}
- if (!setCloseOnExec(xwmFDs[0], true) || !setCloseOnExec(xwmFDs[1], true)) {
+ xwmFDs[0] = CFileDescriptor{xwmPair[0]};
+ xwmFDs[1] = CFileDescriptor{xwmPair[1]};
+
+ if (!xwmFDs[0].setFlags(xwmFDs[0].getFlags() | FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() | FD_CLOEXEC)) {
Debug::log(ERR, "set_cloexec failed (2)");
die();
return false;
}
- xwaylandClient = wl_client_create(g_pCompositor->m_sWLDisplay, waylandFDs[0]);
+ xwaylandClient = wl_client_create(g_pCompositor->m_sWLDisplay, waylandFDs[0].get());
if (!xwaylandClient) {
Debug::log(ERR, "wl_client_create failed");
die();
return false;
}
- waylandFDs[0] = -1;
+ waylandFDs[0].take(); // does this leak?
int notify[2] = {-1, -1};
if (pipe(notify) < 0) {
@@ -369,22 +331,20 @@ bool CXWaylandServer::start() {
return false;
}
- if (!setCloseOnExec(notify[0], true)) {
+ CFileDescriptor notifyFds[2] = {CFileDescriptor{notify[0]}, CFileDescriptor{notify[1]}};
+
+ if (!notifyFds[0].setFlags(notifyFds[0].getFlags() | FD_CLOEXEC)) {
Debug::log(ERR, "set_cloexec failed (3)");
- close(notify[0]);
- close(notify[1]);
die();
return false;
}
- pipeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, notify[0], WL_EVENT_READABLE, ::xwaylandReady, nullptr);
- pipeFd = notify[0];
+ pipeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, notifyFds[0].get(), WL_EVENT_READABLE, ::xwaylandReady, nullptr);
+ pipeFd = std::move(notifyFds[0]);
serverPID = fork();
if (serverPID < 0) {
Debug::log(ERR, "fork failed");
- close(notify[0]);
- close(notify[1]);
die();
return false;
} else if (serverPID == 0) {
@@ -393,25 +353,19 @@ bool CXWaylandServer::start() {
Debug::log(ERR, "second fork failed");
_exit(1);
} else if (pid == 0)
- runXWayland(notify[1]);
+ runXWayland(notifyFds[1]);
_exit(0);
}
- close(notify[1]);
- close(waylandFDs[1]);
- closeSocketSafely(xwmFDs[1]);
- waylandFDs[1] = -1;
- xwmFDs[1] = -1;
-
return true;
}
-int CXWaylandServer::ready(int fd, uint32_t mask) {
+int CXWaylandServer::ready(CFileDescriptor fd, uint32_t mask) {
if (mask & WL_EVENT_READABLE) {
// xwayland writes twice
char buf[64];
- ssize_t n = read(fd, buf, sizeof(buf));
+ ssize_t n = read(fd.get(), buf, sizeof(buf));
if (n < 0 && errno != EINTR) {
Debug::log(ERR, "Xwayland: read from displayFd failed");
mask = 0;
@@ -436,7 +390,6 @@ int CXWaylandServer::ready(int fd, uint32_t mask) {
Debug::log(LOG, "XWayland is ready");
- close(fd);
wl_event_source_remove(pipeSource);
pipeSource = nullptr;
diff --git a/src/xwayland/Server.hpp b/src/xwayland/Server.hpp
index 7a36a965..ccbcf6ea 100644
--- a/src/xwayland/Server.hpp
+++ b/src/xwayland/Server.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <array>
+#include <hyprutils/os/FileDescriptor.hpp>
#include "../helpers/signal/Signal.hpp"
struct wl_event_source;
@@ -19,7 +20,7 @@ class CXWaylandServer {
bool start();
// called on ready
- int ready(int fd, uint32_t mask);
+ int ready(Hyprutils::OS::CFileDescriptor fd, uint32_t mask);
void die();
@@ -30,20 +31,20 @@ class CXWaylandServer {
wl_client* xwaylandClient = nullptr;
private:
- bool tryOpenSockets();
- void runXWayland(int notifyFD);
-
- pid_t serverPID = 0;
-
- std::string displayName;
- int display = -1;
- std::array<int, 2> xFDs = {-1, -1};
- std::array<wl_event_source*, 2> xFDReadEvents = {nullptr, nullptr};
- wl_event_source* idleSource = nullptr;
- wl_event_source* pipeSource = nullptr;
- int pipeFd = -1;
- std::array<int, 2> xwmFDs = {-1, -1};
- std::array<int, 2> waylandFDs = {-1, -1};
+ bool tryOpenSockets();
+ void runXWayland(Hyprutils::OS::CFileDescriptor& notifyFD);
+
+ pid_t serverPID = 0;
+
+ std::string displayName;
+ int display = -1;
+ std::array<Hyprutils::OS::CFileDescriptor, 2> xFDs;
+ std::array<wl_event_source*, 2> xFDReadEvents = {nullptr, nullptr};
+ wl_event_source* idleSource = nullptr;
+ wl_event_source* pipeSource = nullptr;
+ Hyprutils::OS::CFileDescriptor pipeFd;
+ std::array<Hyprutils::OS::CFileDescriptor, 2> xwmFDs;
+ std::array<Hyprutils::OS::CFileDescriptor, 2> waylandFDs;
friend class CXWM;
};
diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp
index 4b0c5a29..e6282dcb 100644
--- a/src/xwayland/XDataSource.cpp
+++ b/src/xwayland/XDataSource.cpp
@@ -5,6 +5,7 @@
#include "XDataSource.hpp"
#include <fcntl.h>
+using namespace Hyprutils::OS;
CXDataSource::CXDataSource(SXSelection& sel_) : selection(sel_) {
xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->pWM->connection,
@@ -47,7 +48,7 @@ std::vector<std::string> CXDataSource::mimes() {
return mimeTypes;
}
-void CXDataSource::send(const std::string& mime, uint32_t fd) {
+void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
xcb_atom_t mimeAtom = 0;
if (mime == "text/plain")
@@ -65,11 +66,10 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) {
if (!mimeAtom) {
Debug::log(ERR, "[XDataSource] mime atom not found");
- close(fd);
return;
}
- Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd);
+ Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get());
selection.transfer = makeUnique<SXTransfer>(selection);
selection.transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection);
@@ -81,8 +81,9 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) {
xcb_flush(g_pXWayland->pWM->connection);
- fcntl(fd, F_SETFL, O_WRONLY | O_NONBLOCK);
- selection.transfer->wlFD = fd;
+ //TODO: make CFileDescriptor setflags take SETFL aswell
+ fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK);
+ selection.transfer->wlFD = std::move(fd);
}
void CXDataSource::accepted(const std::string& mime) {
@@ -101,4 +102,4 @@ eDataSourceType CXDataSource::type() {
return DATA_SOURCE_TYPE_X11;
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/xwayland/XDataSource.hpp b/src/xwayland/XDataSource.hpp
index c629aa2a..a61ffcc9 100644
--- a/src/xwayland/XDataSource.hpp
+++ b/src/xwayland/XDataSource.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "../protocols/types/DataDevice.hpp"
+#include <hyprutils/os/FileDescriptor.hpp>
struct SXSelection;
@@ -9,7 +10,7 @@ class CXDataSource : public IDataSource {
CXDataSource(SXSelection&);
virtual std::vector<std::string> mimes();
- virtual void send(const std::string& mime, uint32_t fd);
+ virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
@@ -19,4 +20,4 @@ class CXDataSource : public IDataSource {
SXSelection& selection;
std::vector<std::string> mimeTypes; // these two have shared idx
std::vector<uint32_t> mimeAtoms; //
-}; \ No newline at end of file
+};
diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp
index 6673105e..81900c7b 100644
--- a/src/xwayland/XWM.cpp
+++ b/src/xwayland/XWM.cpp
@@ -17,6 +17,7 @@
#include "../managers/SeatManager.hpp"
#include "../protocols/XWaylandShell.hpp"
#include "../protocols/core/Compositor.hpp"
+using namespace Hyprutils::OS;
#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f
#define INCR_CHUNK_SIZE (64 * 1024)
@@ -883,7 +884,7 @@ void CXWM::getRenderFormat() {
free(reply);
}
-CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0]) {
+CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0].get()) {
if (connection.hasError()) {
Debug::log(ERR, "[xwm] Couldn't start, error {}", connection.hasError());
@@ -901,7 +902,7 @@ CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0]) {
xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(connection));
screen = screen_iterator.data;
- eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, g_pXWayland->pServer->xwmFDs[0], WL_EVENT_READABLE, ::onX11Event, nullptr);
+ eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, g_pXWayland->pServer->xwmFDs[0].get(), WL_EVENT_READABLE, ::onX11Event, nullptr);
wl_event_source_check(eventSource);
gatherResources();
@@ -1180,13 +1181,12 @@ void CXWM::getTransferData(SXSelection& sel) {
if (sel.transfer->propertyReply->type == HYPRATOMS["INCR"]) {
Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :(");
- close(sel.transfer->wlFD);
sel.transfer.reset();
return;
} else {
sel.onWrite();
if (sel.transfer)
- sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD, WL_EVENT_WRITABLE, ::writeDataSource, &sel);
+ sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD.get(), WL_EVENT_WRITABLE, ::writeDataSource, &sel);
}
}
@@ -1361,13 +1361,13 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
// the wayland client might not expect a non-blocking fd
// fcntl(p[1], F_SETFL, O_NONBLOCK);
- transfer->wlFD = p[0];
+ transfer->wlFD = CFileDescriptor{p[0]};
Debug::log(LOG, "[xwm] sending wayland selection to xwayland with mime {}, target {}, fds {} {}", mime, e->target, p[0], p[1]);
- selection->send(mime, p[1]);
+ selection->send(mime, CFileDescriptor{p[1]});
- transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD, WL_EVENT_READABLE, ::readDataSource, this);
+ transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this);
return true;
}
@@ -1376,10 +1376,9 @@ int SXSelection::onWrite() {
char* property = (char*)xcb_get_property_value(transfer->propertyReply);
int remainder = xcb_get_property_value_length(transfer->propertyReply) - transfer->propertyStart;
- ssize_t len = write(transfer->wlFD, property + transfer->propertyStart, remainder);
+ ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder);
if (len == -1) {
Debug::log(ERR, "[xwm] write died in transfer get");
- close(transfer->wlFD);
transfer.reset();
return 0;
}
@@ -1389,7 +1388,6 @@ int SXSelection::onWrite() {
Debug::log(LOG, "[xwm] wl client read partially: len {}", len);
} else {
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
- close(transfer->wlFD);
transfer.reset();
}
@@ -1397,8 +1395,6 @@ int SXSelection::onWrite() {
}
SXTransfer::~SXTransfer() {
- if (wlFD)
- close(wlFD);
if (eventSource)
wl_event_source_remove(eventSource);
if (incomingWindow)
diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp
index dfaf33b9..73a02a86 100644
--- a/src/xwayland/XWM.hpp
+++ b/src/xwayland/XWM.hpp
@@ -10,6 +10,7 @@
#include <xcb/xfixes.h>
#include <xcb/composite.h>
#include <xcb/xcb_errors.h>
+#include <hyprutils/os/FileDescriptor.hpp>
struct wl_event_source;
class CXWaylandSurfaceResource;
@@ -18,25 +19,25 @@ struct SXSelection;
struct SXTransfer {
~SXTransfer();
- SXSelection& selection;
- bool out = true;
+ SXSelection& selection;
+ bool out = true;
- bool incremental = false;
- bool flushOnDelete = false;
- bool propertySet = false;
+ bool incremental = false;
+ bool flushOnDelete = false;
+ bool propertySet = false;
- int wlFD = -1;
- wl_event_source* eventSource = nullptr;
+ Hyprutils::OS::CFileDescriptor wlFD;
+ wl_event_source* eventSource = nullptr;
- std::vector<uint8_t> data;
+ std::vector<uint8_t> data;
- xcb_selection_request_event_t request;
+ xcb_selection_request_event_t request;
- int propertyStart;
- xcb_get_property_reply_t* propertyReply;
- xcb_window_t incomingWindow;
+ int propertyStart;
+ xcb_get_property_reply_t* propertyReply;
+ xcb_window_t incomingWindow;
- bool getIncomingSelectionProp(bool erase);
+ bool getIncomingSelectionProp(bool erase);
};
struct SXSelection {