Skip to content

Commit

Permalink
filedescriptor: implent a new FileDescriptor class
Browse files Browse the repository at this point in the history
makes you able to RAII the filedescriptor making it somewhat easier to
not leak.
  • Loading branch information
gulafaran committed Nov 20, 2024
1 parent e911361 commit ff8bfec
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
33 changes: 33 additions & 0 deletions include/hyprutils/utils/FileDescriptor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

namespace Hyprutils {
namespace Utils {
class CFileDescriptor {
public:
CFileDescriptor() = default;
explicit CFileDescriptor(int fd);
CFileDescriptor(CFileDescriptor&&);
CFileDescriptor& operator=(CFileDescriptor&&);
~CFileDescriptor();

bool operator==(const CFileDescriptor& rhs) const {
return m_fd == rhs.m_fd;
}

bool isValid() const;
int get() const;
int take();
void reset();
CFileDescriptor duplicate() const;

bool isReadable() const;
bool isClosed() const;

static bool isReadable(int fd);
static bool isClosed(int fd);

private:
int m_fd = -1;
};
};
};
77 changes: 77 additions & 0 deletions src/utils/FileDescriptor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <hyprutils/utils/FileDescriptor.hpp>
#include <fcntl.h>
#include <sys/poll.h>
#include <unistd.h>
#include <utility>

using namespace Hyprutils::Utils;

CFileDescriptor::CFileDescriptor(int fd) : m_fd(fd) {}

CFileDescriptor::CFileDescriptor(CFileDescriptor&& other) : m_fd(std::exchange(other.m_fd, -1)) {}

CFileDescriptor& CFileDescriptor::operator=(CFileDescriptor&& other) {
if (this == &other)
return *this;

reset();
m_fd = std::exchange(other.m_fd, -1);
return *this;
}

CFileDescriptor::~CFileDescriptor() {
reset();
}

bool CFileDescriptor::isValid() const {
return m_fd != -1;
}

int CFileDescriptor::get() const {
return m_fd;
}

int CFileDescriptor::take() {
return std::exchange(m_fd, -1);
}

void CFileDescriptor::reset() {
if (m_fd != -1) {
close(m_fd);
m_fd = -1;
}
}

CFileDescriptor CFileDescriptor::duplicate() const {
if (m_fd == -1)
return {};

return CFileDescriptor{fcntl(m_fd, F_DUPFD_CLOEXEC, 0)};
}

bool CFileDescriptor::isClosed() const {
return isClosed(m_fd);
}

bool CFileDescriptor::isReadable() const {
return isReadable(m_fd);
}

bool CFileDescriptor::isClosed(int fd) {
pollfd pfd = {
.fd = fd,
.events = POLLIN,
.revents = 0,
};

if (poll(&pfd, 1, 0) < 0)
return true;

return pfd.revents & (POLLHUP | POLLERR);
}

bool CFileDescriptor::isReadable(int fd) {
pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};

return poll(&pfd, 1, 0) > 0 && (pfd.revents & POLLIN);
}

0 comments on commit ff8bfec

Please sign in to comment.