diff options
Diffstat (limited to 'src/systemctl')
-rw-r--r-- | src/systemctl/systemctl.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 00cd252351..94b225cb31 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -245,6 +245,64 @@ static int translate_bus_error_to_exit_status(int r, const DBusError *error) { return EXIT_FAILURE; } +static int bus_method_call_with_reply(DBusConnection *bus, + const char *destination, + const char *path, + const char *interface, + const char *method, + DBusMessage **return_reply, + DBusError *return_error, + int first_arg_type, ...) { + DBusError error; + DBusMessage *m, *reply; + va_list ap; + int r = 0; + + dbus_error_init(&error); + assert(bus); + + m = dbus_message_new_method_call(destination, path, interface, method); + if (!m) { + r = log_oom(); + goto finish; + } + + va_start(ap, first_arg_type); + if (!dbus_message_append_args_valist(m, first_arg_type, ap)) { + va_end(ap); + dbus_message_unref(m); + r = log_oom(); + goto finish; + } + va_end(ap); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + dbus_message_unref(m); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + if (error_is_no_service(&error)) + r = -ENOENT; + else if (dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED)) + r = -EACCES; + else if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY)) + r = -ETIMEDOUT; + else + r = -EIO; + goto finish; + } + if (return_reply) + *return_reply = reply; + else + dbus_message_unref(reply); +finish: + if(return_error) + *return_error=error; + else + dbus_error_free(&error); + + return r; +} + static void warn_wall(enum action a) { static const char *table[_ACTION_MAX] = { [ACTION_HALT] = "The system is going down for system halt NOW!", |