blob: 8416d6bcd2d7a89db8fcf3c7a1bd70b23051eebe [file] [log] [blame]
#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