File indexing completed on 2024-05-19 05:32:29

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText:: 2022 Xaver Hugl <xaver.hugl@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include "filedescriptor.h"
0010 
0011 #include <fcntl.h>
0012 #include <sys/poll.h>
0013 #include <unistd.h>
0014 #include <utility>
0015 
0016 namespace KWin
0017 {
0018 
0019 FileDescriptor::FileDescriptor(int fd)
0020     : m_fd(fd)
0021 {
0022 }
0023 
0024 FileDescriptor::FileDescriptor(FileDescriptor &&other)
0025     : m_fd(std::exchange(other.m_fd, -1))
0026 {
0027 }
0028 
0029 FileDescriptor &FileDescriptor::operator=(FileDescriptor &&other)
0030 {
0031     if (m_fd != -1) {
0032         ::close(m_fd);
0033     }
0034     m_fd = std::exchange(other.m_fd, -1);
0035     return *this;
0036 }
0037 
0038 FileDescriptor::~FileDescriptor()
0039 {
0040     if (m_fd != -1) {
0041         ::close(m_fd);
0042     }
0043 }
0044 
0045 bool FileDescriptor::isValid() const
0046 {
0047     return m_fd != -1;
0048 }
0049 
0050 int FileDescriptor::get() const
0051 {
0052     return m_fd;
0053 }
0054 
0055 int FileDescriptor::take()
0056 {
0057     return std::exchange(m_fd, -1);
0058 }
0059 
0060 void FileDescriptor::reset()
0061 {
0062     if (m_fd != -1) {
0063         ::close(m_fd);
0064         m_fd = -1;
0065     }
0066 }
0067 
0068 FileDescriptor FileDescriptor::duplicate() const
0069 {
0070     if (m_fd != -1) {
0071         return FileDescriptor{fcntl(m_fd, F_DUPFD_CLOEXEC, 0)};
0072     } else {
0073         return {};
0074     }
0075 }
0076 
0077 bool FileDescriptor::isClosed() const
0078 {
0079     return isClosed(m_fd);
0080 }
0081 
0082 bool FileDescriptor::isReadable() const
0083 {
0084     return isReadable(m_fd);
0085 }
0086 
0087 bool FileDescriptor::isClosed(int fd)
0088 {
0089     pollfd pfd = {
0090         .fd = fd,
0091         .events = POLLIN,
0092         .revents = 0,
0093     };
0094     if (poll(&pfd, 1, 0) < 0) {
0095         return true;
0096     }
0097     return pfd.revents & (POLLHUP | POLLERR);
0098 }
0099 
0100 bool FileDescriptor::isReadable(int fd)
0101 {
0102     pollfd pfd = {
0103         .fd = fd,
0104         .events = POLLIN,
0105         .revents = 0,
0106     };
0107     return poll(&pfd, 1, 0) && (pfd.revents & (POLLIN | POLLNVAL)) != 0;
0108 }
0109 }