Copied FFDCFile and supporting code from phosphor-power
Change-Id: Ife659c941c70f66edcb531df2e0d4da8bf158b06
diff --git a/util/file_descriptor.hpp b/util/file_descriptor.hpp
new file mode 100644
index 0000000..51c125e
--- /dev/null
+++ b/util/file_descriptor.hpp
@@ -0,0 +1,134 @@
+#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