File indexing completed on 2024-11-10 04:57:22
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 }