, m_dbus_systemd_destination("org.freedesktop.systemd1")
, m_dbus_systemd_path("/org/freedesktop/systemd1")
, m_dbus_systemd_manager_interface("org.freedesktop.systemd1.Manager")
+ , m_dbus_systemd_properties_interface("org.freedesktop.DBus.Properties")
+ , m_dbus_systemd_service_interface("org.freedesktop.systemd1.Service")
{
dbus_error_init(&m_err);
connectToDBus();
"Error in dbus_bus_request_name: " << m_err.message);
}
+void DBusAccess::getUnitPath() {
+ newMethodCall("GetUnit");
+ appendToMsg(m_service_name.c_str());
+ sendMsgWithReply();
+ getMsgReply();
+ m_unitPath = handleObjectPathMsgReply();
+}
+
void DBusAccess::newMethodCall(const char *method) {
m_msg = dbus_message_new_method_call(m_dbus_systemd_destination.c_str(),
m_dbus_systemd_path.c_str(),
return ret;
}
+uint32_t DBusAccess::handleVariantUIntMsgReply() {
+ DBusMessageIter iter, iter2;
+
+ RUNNER_ASSERT_MSG(dbus_message_iter_init(m_msg, &iter) != 0,
+ "Message has no arguments");
+ if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&iter)) {
+ RUNNER_FAIL_MSG("Variant type expected");
+ }
+
+ dbus_message_iter_recurse(&iter, &iter2);
+ if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&iter2)) {
+ RUNNER_FAIL_MSG("uint32 type expected");
+ }
+
+ uint32_t ret;
+ dbus_message_iter_get_basic(&iter2, &ret);
+
+ finalizeMsgReply();
+ return ret;
+}
+
void DBusAccess::finalizeMsgReply() {
dbus_message_unref(m_msg);
dbus_pending_call_unref(m_pending);
[](void*)->void {});
subscribeSignals();
requestName();
+ getUnitPath();
}
void DBusAccess::sendToService(const char *method) {
m_runningJobs.insert(handleObjectPathMsgReply());
}
+uint32_t DBusAccess::getUIntProperty(const char *interface, const char *property)
+{
+ m_msg = dbus_message_new_method_call(m_dbus_systemd_destination.c_str(),
+ m_unitPath.c_str(),
+ m_dbus_systemd_properties_interface.c_str(),
+ "Get");
+
+ appendToMsg(interface);
+ appendToMsg(property);
+ sendMsgWithReply();
+ getMsgReply();
+ return handleVariantUIntMsgReply();
+}
+
void DBusAccess::sendResetFailedToService() {
newMethodCall("ResetFailedUnit");
appendToMsg(m_service_name.c_str());
sendResetFailedToService();
}
+pid_t DBusAccess::getServicePid() {
+ return static_cast<pid_t>(getUIntProperty(m_dbus_systemd_service_interface.c_str(), "MainPID"));
+}
+
DBusAccess::~DBusAccess() {
dbus_connection_close(m_conn);
if (m_conn)
void startService();
void stopService();
void restartService();
+ pid_t getServicePid();
virtual ~DBusAccess();
private:
void addBusMatch(const char *member);
void subscribeSignals();
void requestName();
+ void getUnitPath();
void newMethodCall(const char *method);
void appendToMsg(const char *argument);
void sendMsgWithReply();
void getMsgReply();
std::string handleObjectPathMsgReply();
+ uint32_t handleVariantUIntMsgReply();
void finalizeMsgReply();
void connectToDBus();
void sendToService(const char *method);
+ uint32_t getUIntProperty(const char *interface, const char *property);
void sendResetFailedToService();
static DBusHandlerResult messageHandler(DBusConnection *conn, DBusMessage *msg, void *t);
const std::string m_dbus_client_name;
const std::string m_service_name;
+ std::string m_unitPath;
const std::string m_dbus_systemd_destination;
const std::string m_dbus_systemd_path;
const std::string m_dbus_systemd_manager_interface;
+ const std::string m_dbus_systemd_properties_interface;
+ const std::string m_dbus_systemd_service_interface;
std::set<std::string> m_runningJobs;
};