X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fdbus-common.c;h=0c73d6c6a870b04b1419f6fb9614df56f941a2e8;hp=ab1dc4d7e42f99d484c4014d18277b03bb2b50fc;hb=4db17f291c627c885de668200ff8cce2e57c933f;hpb=669241a076108e0483d7d8475beaa506106d077e diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c index ab1dc4d7e..0c73d6c6a 100644 --- a/src/shared/dbus-common.c +++ b/src/shared/dbus-common.c @@ -32,6 +32,7 @@ #include "log.h" #include "dbus-common.h" #include "util.h" +#include "missing.h" #include "def.h" #include "strv.h" @@ -121,7 +122,7 @@ int bus_connect(DBusBusType t, DBusConnection **_bus, bool *_private, DBusError * try via XDG_RUNTIME_DIR first, then * fallback to normal bus access */ - e = getenv("XDG_RUNTIME_DIR"); + e = secure_getenv("XDG_RUNTIME_DIR"); if (e) { char *p; @@ -1161,7 +1162,7 @@ void bus_async_unregister_and_exit(DBusConnection *bus, const char *name) { return; oom: - log_error("Out of memory."); + log_oom(); if (pending) { dbus_pending_call_cancel(pending); @@ -1237,3 +1238,83 @@ finish: return (pid_t) pid; } + +bool bus_error_is_no_service(const DBusError *error) { + assert(error); + + if (!dbus_error_is_set(error)) + return false; + + if (dbus_error_has_name(error, DBUS_ERROR_NAME_HAS_NO_OWNER)) + return true; + + if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) + return true; + + return startswith(error->name, "org.freedesktop.DBus.Error.Spawn."); +} + +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); + r = log_oom(); + goto finish; + } + va_end(ap); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + if (!return_error) + log_error("Failed to issue method call: %s", bus_error_message(&error)); + + if (bus_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 (m) + dbus_message_unref(m); + + if (return_error) + *return_error = error; + else + dbus_error_free(&error); + + return r; +}