Log failing path after sysfs access failures

Log failing device path and error after a sysfs access failure.
Gracefully exit rather than crash.

Change-Id: I41316e84a70ceda8c166f31ab3269f97978da3ab
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/sysfs.cpp b/sysfs.cpp
index f1f46db..0cc11ef 100644
--- a/sysfs.cpp
+++ b/sysfs.cpp
@@ -15,6 +15,7 @@
  */
 #include <cstdlib>
 #include <memory>
+#include <phosphor-logging/log.hpp>
 #include "sysfs.hpp"
 #include "util.hpp"
 #include "directory.hpp"
@@ -51,4 +52,46 @@
     return std::string();
 }
 
+int readSysfsWithCallout(const std::string& root,
+                         const std::string& instance,
+                         const std::string& type,
+                         const std::string& id,
+                         const std::string& sensor)
+{
+    int value = 0;
+    std::string instancePath = root + '/' + instance;
+    std::string fullPath = make_sysfs_path(instancePath,
+                                           type, id, sensor);
+    std::ifstream ifs;
+
+    ifs.exceptions(std::ifstream::failbit
+                   | std::ifstream::badbit
+                   | std::ifstream::eofbit);
+    try
+    {
+        ifs.open(fullPath);
+        ifs >> value;
+    }
+    catch (const std::exception& e)
+    {
+        // Too many GCC bugs (53984, 66145) to do
+        // this the right way...
+        using Cleanup = phosphor::utility::Free<char>;
+
+        // errno should still reflect the error from the failing open
+        // or read system calls that got us here.
+        auto rc = errno;
+        std::string devicePath = instancePath + "/device";
+        auto real = std::unique_ptr<char, Cleanup>(
+                        realpath(devicePath.c_str(), nullptr));
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            strerror(rc),
+            phosphor::logging::entry("CALLOUT_DEVICE_PATH=%s", real.get()),
+            phosphor::logging::entry("CALLOUT_ERRNO=%d", rc));
+        exit(EXIT_FAILURE);
+    }
+
+    return value;
+}
+
 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4