I also implemented some systemd stuff in C++. Here was my solution:
std::string Unit::GetPropertyString(const std::string& property) const
{
sd_bus_error err = SD_BUS_ERROR_NULL;
char* msg = nullptr;
int r;
r = sd_bus_get_property_string(m_bus,
"org.freedesktop.systemd1",
("/org/freedesktop/systemd1/unit/" + m_unit).c_str(),
"org.freedesktop.systemd1.Unit",
property.c_str(),
&err,
&msg);
if (r < 0)
{
std::string err_msg(err.message);
sd_bus_error_free(&err);
std::string err_str("Failed to get " + property + " for service "
+ m_name + ". Error: " + err_msg);
throw slib_exception(err_str);
}
sd_bus_error_free(&err);
// Free memory (avoid leaking)
std::string ret(msg);
free (msg);
return ret;
}
From this, you can call
activestate = GetPropertyString("ActiveState");
substate = GetPropertyString("SubState");
I found that a lot of the <systemd/sd-bus.h>
wasn't well documented. There is a fantastic explanation by the author here:
http://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html
But outside of the few examples he gives, I found it was easier to inspect the source code. Specifically, I found it nice looking into the source-code of the systemctl
and journalctl
applications to see how sd-bus
was used in those contexts.