diff options
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 100 |
1 files changed, 73 insertions, 27 deletions
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 7e7ebb27a7..2f5e483ae2 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -22,8 +22,10 @@ #include <netdb.h> #include <poll.h> #include <pthread.h> +#include <signal.h> #include <stdlib.h> #include <sys/mman.h> +#include <sys/wait.h> #include <unistd.h> #include "sd-bus.h" @@ -286,8 +288,7 @@ _public_ int sd_bus_set_address(sd_bus *bus, const char *address) { if (!a) return -ENOMEM; - free(bus->address); - bus->address = a; + free_and_replace(bus->address, a); return 0; } @@ -325,10 +326,9 @@ _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) return -ENOMEM; } - free(bus->exec_path); - strv_free(bus->exec_argv); + free_and_replace(bus->exec_path, p); - bus->exec_path = p; + strv_free(bus->exec_argv); bus->exec_argv = a; return 0; @@ -351,7 +351,7 @@ _public_ int sd_bus_set_monitor(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - bus->is_monitor = b; + bus->is_monitor = !!b; return 0; } @@ -361,7 +361,7 @@ _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - bus->accept_fd = b; + bus->accept_fd = !!b; return 0; } @@ -373,7 +373,7 @@ _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) { /* This is not actually supported by any of our transports these days, but we do honour it for synthetic * replies, and maybe one day classic D-Bus learns this too */ - bus->attach_timestamp = b; + bus->attach_timestamp = !!b; return 0; } @@ -457,7 +457,7 @@ _public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - bus->watch_bind = b; + bus->watch_bind = !!b; return 0; } @@ -475,7 +475,7 @@ _public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - bus->connected_signal = b; + bus->connected_signal = !!b; return 0; } @@ -556,6 +556,7 @@ void bus_set_state(sd_bus *bus, enum bus_state state) { static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { const char *s; + char *t; sd_bus *bus; int r; @@ -575,10 +576,12 @@ static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *e if (!service_name_is_valid(s) || s[0] != ':') return -EBADMSG; - bus->unique_name = strdup(s); - if (!bus->unique_name) + t = strdup(s); + if (!t) return -ENOMEM; + free_and_replace(bus->unique_name, t); + if (bus->state == BUS_HELLO) { bus_set_state(bus, BUS_RUNNING); @@ -649,8 +652,8 @@ int bus_start_running(sd_bus *bus) { static int parse_address_key(const char **p, const char *key, char **value) { size_t l, n = 0, allocated = 0; + _cleanup_free_ char *r = NULL; const char *a; - char *r = NULL; assert(p); assert(*p); @@ -678,16 +681,12 @@ static int parse_address_key(const char **p, const char *key, char **value) { int x, y; x = unhexchar(a[1]); - if (x < 0) { - free(r); + if (x < 0) return x; - } y = unhexchar(a[2]); - if (y < 0) { - free(r); + if (y < 0) return y; - } c = (char) ((x << 4) | y); a += 3; @@ -714,8 +713,7 @@ static int parse_address_key(const char **p, const char *key, char **value) { *p = a; - free(*value); - *value = r; + free_and_replace(*value, r); return 1; } @@ -1099,6 +1097,13 @@ static int bus_parse_next_address(sd_bus *b) { return 1; } +static void bus_kill_exec(sd_bus *bus) { + if (pid_is_valid(bus->busexec_pid) > 0) { + sigterm_wait(bus->busexec_pid); + bus->busexec_pid = 0; + } +} + static int bus_start_address(sd_bus *b) { int r; @@ -1108,6 +1113,8 @@ static int bus_start_address(sd_bus *b) { bus_close_io_fds(b); bus_close_inotify_fd(b); + bus_kill_exec(b); + /* If you provide multiple different bus-addresses, we * try all of them in order and use the first one that * succeeds. */ @@ -1377,7 +1384,7 @@ fail: int bus_set_address_system_remote(sd_bus *b, const char *host) { _cleanup_free_ char *e = NULL; - char *m = NULL, *c = NULL; + char *m = NULL, *c = NULL, *a; assert(b); assert(host); @@ -1408,10 +1415,12 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) { return -ENOMEM; } - b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=--,argv3=", e, ",argv4=systemd-stdio-bridge", c); - if (!b->address) + a = strjoin("unixexec:path=ssh,argv1=-xT,argv2=--,argv3=", e, ",argv4=systemd-stdio-bridge", c); + if (!a) return -ENOMEM; + free_and_replace(b->address, a); + return 0; } @@ -1449,6 +1458,7 @@ fail: int bus_set_address_system_machine(sd_bus *b, const char *machine) { _cleanup_free_ char *e = NULL; + char *a; assert(b); assert(machine); @@ -1457,10 +1467,12 @@ int bus_set_address_system_machine(sd_bus *b, const char *machine) { if (!e) return -ENOMEM; - b->address = strjoin("x-machine-unix:machine=", e); - if (!b->address) + a = strjoin("x-machine-unix:machine=", e); + if (!a) return -ENOMEM; + free_and_replace(b->address, a); + return 0; } @@ -1506,6 +1518,9 @@ _public_ void sd_bus_close(sd_bus *bus) { if (bus_pid_changed(bus)) return; + /* Don't leave ssh hanging around */ + bus_kill_exec(bus); + bus_set_state(bus, BUS_CLOSED); sd_bus_detach_event(bus); @@ -1523,6 +1538,9 @@ _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) { if (!bus) return NULL; + /* Have to do this before flush() to prevent hang */ + bus_kill_exec(bus); + sd_bus_flush(bus); sd_bus_close(bus); @@ -3902,7 +3920,15 @@ _public_ int sd_bus_get_description(sd_bus *bus, const char **description) { assert_return(bus->description, -ENXIO); assert_return(!bus_pid_changed(bus), -ECHILD); - *description = bus->description; + if (bus->description) + *description = bus->description; + else if (bus->is_system) + *description = "system"; + else if (bus->is_user) + *description = "user"; + else + *description = NULL; + return 0; } @@ -4065,3 +4091,23 @@ _public_ int sd_bus_get_sender(sd_bus *bus, const char **ret) { *ret = bus->patch_sender; return 0; } + +_public_ int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(ret, -EINVAL); + + *ret = bus->rqueue_size; + return 0; +} + +_public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) { + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(ret, -EINVAL); + + *ret = bus->wqueue_size; + return 0; +} |