exception: Add .get_errno() method

Add the .get_errno() method to provide the errno value from SdBusError.

Closes openbmc/sdbusplus#22

Tested: Added check for the new method to the exception
unit test suite. Also verified external callers get the right
errno value with:
    catch (const SdBusError& e)
    {
        int errno = e.get_errno());
    }

Change-Id: Idddfa7f1bd9cfabfaf89e4d6c83146b4b9af211f
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/sdbusplus/exception.cpp b/sdbusplus/exception.cpp
index 3dea6f9..a0ecc8d 100644
--- a/sdbusplus/exception.cpp
+++ b/sdbusplus/exception.cpp
@@ -68,6 +68,11 @@
     return full_message.c_str();
 }
 
+int SdBusError::get_errno() const noexcept
+{
+    return intf->sd_bus_error_get_errno(&this->error);
+}
+
 void SdBusError::populateMessage(const char* prefix)
 {
     full_message = prefix;
diff --git a/sdbusplus/exception.hpp b/sdbusplus/exception.hpp
index 6fe8d70..2eca532 100644
--- a/sdbusplus/exception.hpp
+++ b/sdbusplus/exception.hpp
@@ -45,6 +45,7 @@
     const char* name() const noexcept override;
     const char* description() const noexcept override;
     const char* what() const noexcept override;
+    int get_errno() const noexcept;
 
   private:
     sd_bus_error error;
diff --git a/test/exception/sdbus_error.cpp b/test/exception/sdbus_error.cpp
index 40d88ee..fde0a85 100644
--- a/test/exception/sdbus_error.cpp
+++ b/test/exception/sdbus_error.cpp
@@ -34,6 +34,8 @@
 
     // Make sure inheritance is defined correctly
     sdbusplus::exception::exception& sdbusErr = err;
+    SdBusError& errNew = err;
+    EXPECT_EQ(errorVal, errNew.get_errno());
     EXPECT_EQ(std::string{error.name}, sdbusErr.name());
     EXPECT_EQ(std::string{error.message}, sdbusErr.description());
     std::exception& stdErr = sdbusErr;
@@ -80,6 +82,7 @@
         // Build our first SdBusError
         SdBusError err(errorVal, prefix.c_str());
 
+        EXPECT_EQ(errorVal, err.get_errno());
         EXPECT_EQ(name, err.name());
         EXPECT_EQ(message, err.description());
         EXPECT_EQ(what, err.what());
@@ -88,11 +91,13 @@
         SdBusError errNew(std::move(err));
 
         // Ensure the old object was cleaned up
+        EXPECT_EQ(0, err.get_errno());
         EXPECT_EQ(nullptr, err.name());
         EXPECT_EQ(nullptr, err.description());
         EXPECT_EQ(std::string{}, err.what());
 
         // Ensure our new object has the same data but moved
+        EXPECT_EQ(errorVal, errNew.get_errno());
         EXPECT_EQ(name, errNew.name());
         EXPECT_EQ(message, errNew.description());
         EXPECT_EQ(what, errNew.what());
@@ -101,12 +106,14 @@
         errFinal = std::move(errNew);
 
         // Ensure the old object was cleaned up
+        EXPECT_EQ(0, errNew.get_errno());
         EXPECT_EQ(nullptr, errNew.name());
         EXPECT_EQ(nullptr, errNew.description());
         EXPECT_EQ(std::string{}, errNew.what());
     }
 
     // Ensure our new object has the same data but moved
+    EXPECT_EQ(errorVal, errFinal.get_errno());
     EXPECT_EQ(name, errFinal.name());
     EXPECT_EQ(message, errFinal.description());
     EXPECT_EQ(what, errFinal.what());
@@ -124,6 +131,7 @@
     sd_bus_error_set(&error, name.c_str(), description.c_str());
     EXPECT_TRUE(sd_bus_error_is_set(&error));
     const char* nameBeforeMove = error.name;
+    const int errorVal = sd_bus_error_get_errno(&error);
     SdBusError err(&error, prefix.c_str());
 
     // We expect a move not copy
@@ -134,6 +142,7 @@
     sd_bus_error_free(&error);
     sd_bus_error_free(&error);
 
+    EXPECT_EQ(errorVal, err.get_errno());
     EXPECT_EQ(name, err.name());
     EXPECT_EQ(description, err.description());
     EXPECT_EQ(prefix + ": " + name + ": " + description, err.what());