X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fsd-bus.c;h=ca7c428a31628d043d94a83e3705d8db6689a919;hb=82923adfe5c4fa09cc91fd2a2e374c936cd4a186;hp=427d53061c58391d29792265a278c5f65aa36af1;hpb=151b9b9662a90455262ce575a8a8ae74bf4ff336;p=elogind.git diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 427d53061..ca7c428a3 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -36,6 +36,7 @@ #include "missing.h" #include "def.h" #include "cgroup-util.h" +#include "bus-label.h" #include "sd-bus.h" #include "bus-internal.h" @@ -50,6 +51,7 @@ #include "bus-util.h" #include "bus-container.h" #include "bus-protocol.h" +#include "bus-track.h" static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec); static int attach_io_events(sd_bus *b); @@ -130,6 +132,8 @@ static void bus_free(sd_bus *b) { assert(b); + assert(!b->track_queue); + sd_bus_detach_event(b); if (b->default_bus_ptr) @@ -794,7 +798,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) b->sockaddr.un.sun_family = AF_UNIX; strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path)); - b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1; + b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket"); return 0; } @@ -1185,7 +1189,8 @@ _public_ int sd_bus_open_user(sd_bus **ret) { #ifdef ENABLE_KDBUS asprintf(&b->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid()); #else - return -ECONNREFUSED; + r = -ECONNREFUSED; + goto fail; #endif } @@ -1999,6 +2004,11 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) { assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN); assert_return(!bus_pid_changed(bus), -ECHILD); + if (bus->track_queue) { + *timeout_usec = 0; + return 1; + } + if (bus->state == BUS_CLOSING) { *timeout_usec = 0; return 1; @@ -2281,6 +2291,16 @@ finish: return r; } +static int dispatch_track(sd_bus *bus) { + assert(bus); + + if (!bus->track_queue) + return 0; + + bus_track_dispatch(bus->track_queue); + return 1; +} + static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; int r; @@ -2296,6 +2316,10 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd if (r != 0) goto null_message; + r = dispatch_track(bus); + if (r != 0) + goto null_message; + r = dispatch_rqueue(bus, hint_priority, priority, &m); if (r < 0) return r; @@ -3040,76 +3064,46 @@ _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) { return -ENXIO; } -_public_ char *sd_bus_label_escape(const char *s) { - char *r, *t; - const char *f; - - assert_return(s, NULL); - - /* Escapes all chars that D-Bus' object path cannot deal - * with. Can be reversed with bus_path_unescape(). We special - * case the empty string. */ - - if (*s == 0) - return strdup("_"); - - r = new(char, strlen(s)*3 + 1); - if (!r) - return NULL; - - for (f = s, t = r; *f; f++) { +_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) { + _cleanup_free_ char *e = NULL; + char *ret; - /* Escape everything that is not a-zA-Z0-9. We also - * escape 0-9 if it's the first character */ + assert_return(object_path_is_valid(prefix), -EINVAL); + assert_return(external_id, -EINVAL); + assert_return(ret_path, -EINVAL); - if (!(*f >= 'A' && *f <= 'Z') && - !(*f >= 'a' && *f <= 'z') && - !(f > s && *f >= '0' && *f <= '9')) { - *(t++) = '_'; - *(t++) = hexchar(*f >> 4); - *(t++) = hexchar(*f); - } else - *(t++) = *f; - } + e = bus_label_escape(external_id); + if (!e) + return -ENOMEM; - *t = 0; + ret = strjoin(prefix, "/", e, NULL); + if (!ret) + return -ENOMEM; - return r; + *ret_path = ret; + return 0; } -_public_ char *sd_bus_label_unescape(const char *f) { - char *r, *t; - - assert_return(f, NULL); - - /* Special case for the empty string */ - if (streq(f, "_")) - return strdup(""); - - r = new(char, strlen(f) + 1); - if (!r) - return NULL; - - for (t = r; *f; f++) { +_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) { + const char *e; + char *ret; - if (*f == '_') { - int a, b; + assert_return(object_path_is_valid(path), -EINVAL); + assert_return(object_path_is_valid(prefix), -EINVAL); + assert_return(external_id, -EINVAL); - if ((a = unhexchar(f[1])) < 0 || - (b = unhexchar(f[2])) < 0) { - /* Invalid escape code, let's take it literal then */ - *(t++) = '_'; - } else { - *(t++) = (char) ((a << 4) | b); - f += 2; - } - } else - *(t++) = *f; + e = object_path_startswith(path, prefix); + if (!e) { + *external_id = NULL; + return 0; } - *t = 0; + ret = bus_label_unescape(e); + if (!ret) + return -ENOMEM; - return r; + *external_id = ret; + return 1; } _public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {