| #pragma once |
| |
| #include <unistd.h> // for close() |
| |
| namespace util |
| { |
| |
| /** |
| * @class FileDescriptor |
| * |
| * This class manages an open file descriptor. |
| * |
| * The file descriptor can be closed by calling close(). Otherwise it will be |
| * closed by the destructor. |
| * |
| * FileDescriptor objects cannot be copied, but they can be moved. This enables |
| * them to be stored in containers like std::vector. |
| */ |
| class FileDescriptor |
| { |
| public: |
| FileDescriptor() = default; |
| FileDescriptor(const FileDescriptor&) = delete; |
| FileDescriptor& operator=(const FileDescriptor&) = delete; |
| |
| /** |
| * Constructor. |
| * |
| * @param[in] fd - File descriptor |
| */ |
| explicit FileDescriptor(int fd) : fd(fd) {} |
| |
| /** |
| * Move constructor. |
| * |
| * Transfers ownership of a file descriptor. |
| * |
| * @param other - FileDescriptor object being moved |
| */ |
| FileDescriptor(FileDescriptor&& other) : fd(other.fd) |
| { |
| other.fd = -1; |
| } |
| |
| /** |
| * Move assignment operator. |
| * |
| * Closes the file descriptor owned by this object, if any. Then transfers |
| * ownership of the file descriptor owned by the other object. |
| * |
| * @param other - FileDescriptor object being moved |
| */ |
| FileDescriptor& operator=(FileDescriptor&& other) |
| { |
| // Verify not assigning object to itself (a = std::move(a)) |
| if (this != &other) |
| { |
| set(other.fd); |
| other.fd = -1; |
| } |
| return *this; |
| } |
| |
| /** |
| * Destructor. |
| * |
| * Closes the file descriptor if necessary. |
| */ |
| ~FileDescriptor() |
| { |
| close(); |
| } |
| |
| /** |
| * Returns the file descriptor. |
| * |
| * @return File descriptor. Returns -1 if this object does not contain an |
| * open file descriptor. |
| */ |
| int operator()() |
| { |
| return fd; |
| } |
| |
| /** |
| * Returns whether this object contains an open file descriptor. |
| * |
| * @return true if object contains an open file descriptor, false otherwise. |
| */ |
| operator bool() const |
| { |
| return fd != -1; |
| } |
| |
| /** |
| * Closes the file descriptor. |
| * |
| * Does nothing if the file descriptor was not set or was already closed. |
| * |
| * @return 0 if descriptor was successfully closed. Returns -1 if an error |
| * occurred; errno will be set appropriately. |
| */ |
| int close() |
| { |
| int rc = 0; |
| if (fd >= 0) |
| { |
| rc = ::close(fd); |
| fd = -1; |
| } |
| return rc; |
| } |
| |
| /** |
| * Sets the file descriptor. |
| * |
| * Closes the previous file descriptor if necessary. |
| * |
| * @param[in] descriptor - File descriptor |
| */ |
| void set(int descriptor) |
| { |
| close(); |
| fd = descriptor; |
| } |
| |
| private: |
| /** |
| * File descriptor. |
| */ |
| int fd = -1; |
| }; |
| |
| } // namespace util |