elog_entry: Implement getEntry method

The getEntry method returns the file descriptor to the Entry file.
This method uses its File Path property to determine the path to
the Entry file. The file descriptor is then scheduled to be closed
once the D-Bus call returns.

Tested: Verified calling this method returned a fd that was able to
read the file data from.

Change-Id: I176db463158eb755b325db5769ef4ab993c966ec
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/elog_entry.cpp b/elog_entry.cpp
index 36a3fb2..9c5d213 100644
--- a/elog_entry.cpp
+++ b/elog_entry.cpp
@@ -3,6 +3,10 @@
 #include "elog_serialize.hpp"
 #include "log_manager.hpp"
 
+#include <unistd.h>
+
+#include <xyz/openbmc_project/Common/File/error.hpp>
+
 namespace phosphor
 {
 namespace logging
@@ -37,5 +41,34 @@
     return current;
 }
 
+sdbusplus::message::unix_fd Entry::getEntry()
+{
+    FILE* fp = fopen(path().c_str(), "rb");
+    if (fp == nullptr)
+    {
+        auto e = errno;
+        log<level::ERR>("Failed to open Entry File", entry("ERRNO=%d", e),
+                        entry("PATH=%s", path().c_str()));
+        throw sdbusplus::xyz::openbmc_project::Common::File::Error::Open();
+    }
+
+    auto fd = fileno(fp);
+
+    // Schedule the fd to be closed by sdbusplus when it sends it back over
+    // D-Bus.
+    sdeventplus::Event event = sdeventplus::Event::get_default();
+    fdCloseEventSource = std::make_unique<sdeventplus::source::Defer>(
+        event, std::bind(std::mem_fn(&Entry::closeFD), this, fd,
+                         std::placeholders::_1));
+
+    return fd;
+}
+
+void Entry::closeFD(int fd, sdeventplus::source::EventBase& source)
+{
+    close(fd);
+    fdCloseEventSource.reset();
+}
+
 } // namespace logging
 } // namespace phosphor