X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-util.c;h=f96c293984b014220f7d25cc63b721c63e069189;hb=7fb411f035e68b5f3f5e2893157739c9da9917b0;hp=3afcb82bcbe25c776d56e1861c0a6bd795695df1;hpb=11846aa74680bab65711427b1e7702e783b2894c;p=elogind.git diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c index 3afcb82bc..f96c29398 100644 --- a/src/libsystemd-bus/bus-util.c +++ b/src/libsystemd-bus/bus-util.c @@ -35,18 +35,18 @@ #include "bus-util.h" #include "bus-internal.h" -static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { +static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { sd_event *e = userdata; assert(bus); assert(m); assert(e); - sd_event_request_quit(e); + sd_event_exit(e, 0); return 1; } -int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) { +int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { _cleanup_free_ char *match = NULL; const char *unique; int r; @@ -55,6 +55,11 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) { assert(bus); assert(name); + /* We unregister the name here and then wait for the + * NameOwnerChanged signal for this event to arrive before we + * quit. We do this in order to make sure that any queued + * requests are still processed before we really exit. */ + r = sd_bus_get_unique_name(bus, &unique); if (r < 0) return r; @@ -71,7 +76,7 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) { if (r < 0) return -ENOMEM; - r = sd_bus_add_match(bus, match, quit_callback, e); + r = sd_bus_add_match(bus, match, name_owner_change_callback, e); if (r < 0) return r; @@ -82,28 +87,40 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) { return 0; } -int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t timeout) { +int bus_event_loop_with_idle( + sd_event *e, + sd_bus *bus, + const char *name, + usec_t timeout, + check_idle_t check_idle, + void *userdata) { bool exiting = false; - int r; + int r, code; assert(e); assert(bus); assert(name); for (;;) { + bool idle; + r = sd_event_get_state(e); if (r < 0) return r; - if (r == SD_EVENT_FINISHED) break; - r = sd_event_run(e, exiting ? (uint64_t) -1 : timeout); + if (check_idle) + idle = check_idle(userdata); + else + idle = true; + + r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout); if (r < 0) return r; if (r == 0 && !exiting) { - r = bus_async_unregister_and_quit(e, bus, name); + r = bus_async_unregister_and_exit(e, bus, name); if (r < 0) return r; @@ -111,7 +128,11 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t } } - return 0; + r = sd_event_get_exit_code(e, &code); + if (r < 0) + return r; + + return code; } int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) { @@ -203,8 +224,12 @@ int bus_verify_polkit( } r = sd_bus_message_enter_container(reply, 'r', "bba{ss}"); - if (r >= 0) - r = sd_bus_message_read(reply, "bb", &authorized, &challenge); + if (r < 0) + return r; + + r = sd_bus_message_read(reply, "bb", &authorized, &challenge); + if (r < 0) + return r; if (authorized) return 1; @@ -319,7 +344,7 @@ int bus_verify_polkit_async( if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) return -EACCES; - return sd_bus_error_get_errno(e); + return -sd_bus_error_get_errno(e); } r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}"); @@ -988,6 +1013,8 @@ int bus_map_all_properties(sd_bus *bus, r = prop->set(bus, member, m, &error, v); else r = map_basic(bus, member, m, &error, v); + if (r < 0) + return r; r = sd_bus_message_exit_container(m); if (r < 0)