SdBusError: Really own the sd_bus_error
The sd_bus_error constructor claims to own the sd_bus_error pointer but
it doesn't prevent the user from trivially re-using it in a broken way.
Instead of accepting the argument by value, take the old value and
overwrite the caller's copy to NULL it out. This way future calls to
sd_bus_error_free() by the caller will do the right thing.
Tested:
Builds still work and tests are passing.
Change-Id: I0afd856f0a2a08a08f25fd43c051aae4b2a645f4
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/sdbusplus/bus.hpp.in b/sdbusplus/bus.hpp.in
index 473a5ea..7be0b92 100644
--- a/sdbusplus/bus.hpp.in
+++ b/sdbusplus/bus.hpp.in
@@ -247,7 +247,7 @@
&reply);
if (r < 0)
{
- throw exception::SdBusError(error, "sd_bus_call");
+ throw exception::SdBusError(&error, "sd_bus_call");
}
return message::message(reply, _intf, std::false_type());
@@ -265,7 +265,7 @@
nullptr);
if (r < 0)
{
- throw exception::SdBusError(error, "sd_bus_call noreply");
+ throw exception::SdBusError(&error, "sd_bus_call noreply");
}
}
diff --git a/sdbusplus/exception.cpp b/sdbusplus/exception.cpp
index f160c22..e8f1104 100644
--- a/sdbusplus/exception.cpp
+++ b/sdbusplus/exception.cpp
@@ -21,12 +21,15 @@
populateMessage(prefix);
}
-SdBusError::SdBusError(sd_bus_error error, const char* prefix,
+SdBusError::SdBusError(sd_bus_error* error, const char* prefix,
SdBusInterface* intf) :
- std::system_error(intf->sd_bus_error_get_errno(&error),
+ std::system_error(intf->sd_bus_error_get_errno(error),
std::generic_category()),
- error(error), intf(intf)
+ error(*error), intf(intf)
{
+ // We own the error so remove the caller's reference
+ *error = SD_BUS_ERROR_NULL;
+
populateMessage(prefix);
}
diff --git a/sdbusplus/exception.hpp b/sdbusplus/exception.hpp
index 73b26a0..6cfc0f4 100644
--- a/sdbusplus/exception.hpp
+++ b/sdbusplus/exception.hpp
@@ -35,7 +35,7 @@
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;