summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/sd-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c100
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;
+}