diff options
Diffstat (limited to 'src/misc/FileDescriptor.cpp')
| -rw-r--r-- | src/misc/FileDescriptor.cpp | 86 |
1 files changed, 86 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); +} |
