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