1 #pragma once 2 3 #include <unistd.h> // for close() 4 5 namespace watchdog 6 { 7 namespace dump 8 { 9 10 /** 11 * @class FileDescriptor 12 * 13 * This class manages an open file descriptor. 14 * 15 * The file descriptor can be closed by calling close(). Otherwise it will be 16 * closed by the destructor. 17 * 18 * FileDescriptor objects cannot be copied, but they can be moved. This enables 19 * them to be stored in containers like std::vector. 20 */ 21 class FileDescriptor 22 { 23 public: 24 FileDescriptor() = default; 25 FileDescriptor(const FileDescriptor&) = delete; 26 FileDescriptor& operator=(const FileDescriptor&) = delete; 27 28 /** 29 * @brief Constructor 30 * 31 * @param[in] fd - File descriptor 32 */ 33 explicit FileDescriptor(int fd) : fd(fd) 34 {} 35 36 /** 37 * @brief Move constructor. 38 * 39 * @details description ownership of a file descriptor. 40 * 41 * @param other - FileDescriptor object being moved 42 */ 43 FileDescriptor(FileDescriptor&& other) : fd(other.fd) 44 { 45 other.fd = -1; 46 } 47 48 /** 49 * @brief Move assignment operator. 50 * 51 * @details description the file descriptor owned by this object, if any. 52 * Then transfers ownership of the file descriptor owned by the other 53 * object. 54 * 55 * @param other - FileDescriptor object being moved 56 */ 57 FileDescriptor& operator=(FileDescriptor&& other) 58 { 59 // Verify not assigning object to itself (a = std::move(a)) 60 if (this != &other) 61 { 62 set(other.fd); 63 other.fd = -1; 64 } 65 return *this; 66 } 67 68 /** 69 * @brief brief description. 70 * 71 * @details Closes the file descriptor if necessary. 72 */ 73 ~FileDescriptor() 74 { 75 close(); 76 } 77 78 /** 79 * @brief Returns the file descriptor. 80 * 81 * @return File descriptor. Returns -1 if this object does not contain an 82 * open file descriptor. 83 */ 84 int operator()() const 85 { 86 return fd; 87 } 88 89 /** 90 * @brief Check whether this object contains an open file descriptor. 91 * 92 * @return true if object contains an open file descriptor, false otherwise. 93 */ 94 operator bool() const 95 { 96 return fd != -1; 97 } 98 99 /** 100 * @brief Closes the file descriptor. 101 * 102 * @details Does nothing if the file descriptor was not set or was already 103 * closed. 104 * 105 * @return 0 if descriptor was successfully closed. Returns -1 if an error 106 * occurred; errno will be set appropriately. 107 */ 108 int close() 109 { 110 int rc = 0; 111 if (fd >= 0) 112 { 113 rc = ::close(fd); 114 fd = -1; 115 } 116 return rc; 117 } 118 119 /** 120 * @brief Sets the file descriptor. 121 * 122 * @details Closes the previous file descriptor if necessary. 123 * 124 * @param[in] descriptor - File descriptor 125 */ 126 void set(int descriptor) 127 { 128 (void)close(); 129 fd = descriptor; 130 } 131 132 private: 133 /** 134 * @brief File descriptor. 135 */ 136 int fd = -1; 137 }; 138 139 } // namespace dump 140 } // namespace watchdog 141