diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-06-12 21:41:41 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-06-13 20:22:51 +0800 |
| commit | 6f7b994684032060f0a2d7af82f4f3572293b8d6 (patch) | |
| tree | 793d328cbcd6761365267550b55db45aee9b21fc /src/misc | |
| parent | 6a51ab4525c59e9fe2bdbd92493019b0a98c6b94 (diff) | |
internal!: organized internal structure, using cmake now
Diffstat (limited to 'src/misc')
| -rw-r--r-- | src/misc/FileDescriptor.cpp | 86 | ||||
| -rw-r--r-- | src/misc/FileDescriptor.hpp | 35 |
2 files changed, 121 insertions, 0 deletions
diff --git a/src/misc/FileDescriptor.cpp b/src/misc/FileDescriptor.cpp new file mode 100644 index 0000000..92505f5 --- /dev/null +++ b/src/misc/FileDescriptor.cpp @@ -0,0 +1,86 @@ +#include "FileDescriptor.hpp" +#include <cstdlib> +#include <fcntl.h> +#include <sys/poll.h> +#include <unistd.h> +#include <utility> + +CFileDescriptor::CFileDescriptor(int const fd) + : m_fd(fd) {} + +CFileDescriptor::CFileDescriptor(CFileDescriptor &&other) noexcept + : m_fd(std::exchange(other.m_fd, -1)) {} + +CFileDescriptor &CFileDescriptor::operator=(CFileDescriptor &&other) noexcept { + if (this == &other) // Shit will go haywire if there is duplicate ownership + abort(); + + 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::getFlags() const { + return fcntl(m_fd, F_GETFD); +} + +bool CFileDescriptor::setFlags(int flags) { + return fcntl(m_fd, F_SETFD, flags) != -1; +} + +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(int flags) const { + if (m_fd == -1) + return {}; + + return CFileDescriptor{fcntl(m_fd, flags, 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); +} diff --git a/src/misc/FileDescriptor.hpp b/src/misc/FileDescriptor.hpp new file mode 100644 index 0000000..75aeb73 --- /dev/null +++ b/src/misc/FileDescriptor.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include <fcntl.h> +class CFileDescriptor { + public: + CFileDescriptor() = default; + explicit CFileDescriptor(int const fd); + CFileDescriptor(CFileDescriptor &&) noexcept; + CFileDescriptor &operator=(CFileDescriptor &&) noexcept; + ~CFileDescriptor(); + + CFileDescriptor(const CFileDescriptor &) = delete; + CFileDescriptor &operator=(const CFileDescriptor &) = delete; + + bool operator==(const CFileDescriptor &rhs) const { + return m_fd == rhs.m_fd; + } + + bool isValid() const; + int get() const; + int getFlags() const; + bool setFlags(int flags); + int take(); + void reset(); + CFileDescriptor duplicate(int flags = F_DUPFD_CLOEXEC) const; + + bool isReadable() const; + bool isClosed() const; + + static bool isReadable(int fd); + static bool isClosed(int fd); + + private: + int m_fd = -1; +}; |
