SdBusError: Add Dependency Injection for the SdBusInterface

We want to be able to mock some of the sd_bus_error* calls for testing
the SdBusError class. This work makes that possible in the future while
retaining the same behavior.

Tested:
    Errors still work fine and are backward compatible. New test cases
    are now able to build against this class.

Change-Id: Ib125dc48eed60ac2bbdfadc4f1a81c52ab047cd4
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/sdbusplus/exception.cpp b/sdbusplus/exception.cpp
index 5e99abb..f160c22 100644
--- a/sdbusplus/exception.cpp
+++ b/sdbusplus/exception.cpp
@@ -1,15 +1,19 @@
 #include <sdbusplus/exception.hpp>
+#include <sdbusplus/sdbus.hpp>
+
+extern sdbusplus::SdBusImpl sdbus_impl;
 
 namespace sdbusplus
 {
 namespace exception
 {
 
-SdBusError::SdBusError(int error, const char* prefix) :
-    std::system_error(error, std::generic_category()), error(SD_BUS_ERROR_NULL)
+SdBusError::SdBusError(int error, const char* prefix, SdBusInterface* intf) :
+    std::system_error(error, std::generic_category()), error(SD_BUS_ERROR_NULL),
+    intf(intf)
 {
     if (error == ENOMEM ||
-        sd_bus_error_set_errno(&this->error, error) == -ENOMEM)
+        intf->sd_bus_error_set_errno(&this->error, error) == -ENOMEM)
     {
         throw std::bad_alloc();
     }
@@ -17,9 +21,11 @@
     populateMessage(prefix);
 }
 
-SdBusError::SdBusError(sd_bus_error error, const char* prefix) :
-    std::system_error(sd_bus_error_get_errno(&error), std::generic_category()),
-    error(error)
+SdBusError::SdBusError(sd_bus_error error, const char* prefix,
+                       SdBusInterface* intf) :
+    std::system_error(intf->sd_bus_error_get_errno(&error),
+                      std::generic_category()),
+    error(error), intf(intf)
 {
     populateMessage(prefix);
 }
@@ -40,7 +46,7 @@
 
 SdBusError::~SdBusError()
 {
-    sd_bus_error_free(&error);
+    intf->sd_bus_error_free(&error);
 }
 
 const char* SdBusError::name() const noexcept
@@ -75,7 +81,9 @@
 
 void SdBusError::move(SdBusError&& other)
 {
-    sd_bus_error_free(&error);
+    intf = std::move(other.intf);
+
+    intf->sd_bus_error_free(&error);
     error = other.error;
     other.error = SD_BUS_ERROR_NULL;
 
diff --git a/sdbusplus/exception.hpp b/sdbusplus/exception.hpp
index 06f488e..73b26a0 100644
--- a/sdbusplus/exception.hpp
+++ b/sdbusplus/exception.hpp
@@ -1,10 +1,13 @@
 #pragma once
 
 #include <exception>
+#include <sdbusplus/sdbus.hpp>
 #include <string>
 #include <system_error>
 #include <systemd/sd-bus.h>
 
+extern sdbusplus::SdBusImpl sdbus_impl;
+
 namespace sdbusplus
 {
 
@@ -29,9 +32,11 @@
 {
   public:
     /** Errno must be positive */
-    SdBusError(int error, const char* prefix);
+    SdBusError(int error, const char* prefix,
+               SdBusInterface* intf = &sdbus_impl);
     /** Becomes the owner of the error */
-    SdBusError(sd_bus_error error, const char* prefix);
+    SdBusError(sd_bus_error error, const char* prefix,
+               SdBusInterface* intf = &sdbus_impl);
 
     SdBusError(const SdBusError&) = delete;
     SdBusError& operator=(const SdBusError&) = delete;
@@ -46,6 +51,7 @@
   private:
     sd_bus_error error;
     std::string full_message;
+    SdBusInterface* intf;
 
     /** Populates the full_message from the stored
      *  error and the passed in prefix. */