systemctl: add bus_method_call_with_reply
authorSimon Peeters <peeters.simon@gmail.com>
Tue, 7 Aug 2012 23:29:55 +0000 (01:29 +0200)
committerSimon Peeters <peeters.simon@gmail.com>
Tue, 7 Aug 2012 23:29:55 +0000 (01:29 +0200)
this method combines the folowing dbus calls and there error handling:
 dbus_message_new_method_call()
 dbus_message_append_args()
 dbus_connection_send_with_reply_and_block()

src/systemctl/systemctl.c

index 00cd252..94b225c 100644 (file)
@@ -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!",