#pragma once #include <unistd.h> // for close() namespace watchdog { namespace dump { /** * @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; /** * @brief Constructor * * @param[in] fd - File descriptor */ explicit FileDescriptor(int fd) : fd(fd) {} /** * @brief Move constructor. * * @details description ownership of a file descriptor. * * @param other - FileDescriptor object being moved */ FileDescriptor(FileDescriptor&& other) : fd(other.fd) { other.fd = -1; } /** * @brief Move assignment operator. * * @details description 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; } /** * @brief brief description. * * @details Closes the file descriptor if necessary. */ ~FileDescriptor() { close(); } /** * @brief Returns the file descriptor. * * @return File descriptor. Returns -1 if this object does not contain an * open file descriptor. */ int operator()() const { return fd; } /** * @brief Check 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; } /** * @brief Closes the file descriptor. * * @details 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; } /** * @brief Sets the file descriptor. * * @details Closes the previous file descriptor if necessary. * * @param[in] descriptor - File descriptor */ void set(int descriptor) { (void)close(); fd = descriptor; } private: /** * @brief File descriptor. */ int fd = -1; }; } // namespace dump } // namespace watchdog