summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-12-03 18:42:51 +0100
committerLennart Poettering <lennart@poettering.net>2013-12-03 18:42:51 +0100
commit71f2ab468d8413cffdb712083eb4d06dc8b2a271 (patch)
tree231f519dd1dc07ec646090a11b40c83321c82bac
parent0461f8cdc1d7b4afee2f2ff40fcaa3c7e26c662c (diff)
bus: rework sd_bus_list_names() to return two lists for acquired and activatable names
-rw-r--r--src/libsystemd-bus/bus-control.c156
-rw-r--r--src/libsystemd-bus/busctl.c31
-rw-r--r--src/systemd/sd-bus.h2
3 files changed, 125 insertions, 64 deletions
diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index ed10f5a683..d98a4ddf25 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -200,102 +200,142 @@ _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
return bus_release_name_dbus1(bus, name);
}
-static int bus_list_names_kernel(sd_bus *bus, char ***l) {
- _cleanup_free_ struct kdbus_cmd_name_list *cmd = NULL;
+static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
+ struct kdbus_cmd_name_list cmd = {};
struct kdbus_name_list *name_list;
struct kdbus_cmd_name *name;
- char **x = NULL;
int r;
- cmd = malloc0(sizeof(struct kdbus_cmd_name_list));
- if (!cmd)
- return -ENOMEM;
+ /* Caller will free half-constructed list on failure... */
- cmd->size = sizeof(struct kdbus_cmd_name_list);
- cmd->flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES;
+ cmd.size = sizeof(struct kdbus_cmd_name_list);
+ cmd.flags = flags;
- r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, cmd);
+ r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
if (r < 0)
return -errno;
- name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
+ name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
KDBUS_PART_FOREACH(name, name_list, names) {
- char *n;
- if (name->size > sizeof(*name))
- n = name->name;
- else
- asprintf(&n, ":1.%llu", (unsigned long long) name->id);
+ if (name->size > sizeof(*name)) {
+ r = strv_extend(x, name->name);
+ if (r < 0)
+ return -ENOMEM;
+ } else {
+ char *n;
+
+ if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0)
+ return -ENOMEM;
+
+ r = strv_push(x, n);
+ if (r < 0) {
+ free(n);
+ return -ENOMEM;
+ }
+ }
- r = strv_extend(&x, n);
- if (r < 0)
- return -ENOMEM;
}
- r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset);
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd.offset);
if (r < 0)
return -errno;
- *l = x;
return 0;
}
-static int bus_list_names_dbus1(sd_bus *bus, char ***l) {
- _cleanup_bus_message_unref_ sd_bus_message *reply1 = NULL, *reply2 = NULL;
- char **x = NULL;
+static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
+ _cleanup_strv_free_ char **x = NULL, **y = NULL;
int r;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "ListNames",
- NULL,
- &reply1,
- NULL);
- if (r < 0)
- return r;
+ if (acquired) {
+ r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
+ if (r < 0)
+ return r;
+ }
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "ListActivatableNames",
- NULL,
- &reply2,
- NULL);
- if (r < 0)
- return r;
+ if (activatable) {
+ r = kernel_get_list(bus, KDBUS_NAME_LIST_STARTERS, &y);
+ if (r < 0)
+ return r;
- r = bus_message_read_strv_extend(reply1, &x);
- if (r < 0) {
- strv_free(x);
- return r;
+ *activatable = y;
+ y = NULL;
}
- r = bus_message_read_strv_extend(reply2, &x);
- if (r < 0) {
- strv_free(x);
- return r;
+ if (acquired) {
+ *acquired = x;
+ x = NULL;
+ }
+
+ return 0;
+}
+
+static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_strv_free_ char **x = NULL, **y = NULL;
+ int r;
+
+ if (acquired) {
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "ListNames",
+ NULL,
+ &reply,
+ NULL);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_strv(reply, &x);
+ if (r < 0)
+ return r;
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (activatable) {
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "ListActivatableNames",
+ NULL,
+ &reply,
+ NULL);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_strv(reply, &y);
+ if (r < 0)
+ return r;
+
+ *activatable = y;
+ y = NULL;
+ }
+
+ if (acquired) {
+ *acquired = x;
+ x = NULL;
}
- *l = strv_uniq(x);
return 0;
}
-_public_ int sd_bus_list_names(sd_bus *bus, char ***l) {
+_public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
assert_return(bus, -EINVAL);
- assert_return(l, -EINVAL);
+ assert_return(acquired || activatable, -EINVAL);
assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
if (bus->is_kernel)
- return bus_list_names_kernel(bus, l);
+ return bus_list_names_kernel(bus, acquired, activatable);
else
- return bus_list_names_dbus1(bus, l);
+ return bus_list_names_dbus1(bus, acquired, activatable);
}
static int bus_get_owner_kdbus(
diff --git a/src/libsystemd-bus/busctl.c b/src/libsystemd-bus/busctl.c
index f1ae051c9b..bcacfcee85 100644
--- a/src/libsystemd-bus/busctl.c
+++ b/src/libsystemd-bus/busctl.c
@@ -52,14 +52,14 @@ static void pager_open_if_enabled(void) {
}
static int list_bus_names(sd_bus *bus, char **argv) {
- _cleanup_strv_free_ char **l = NULL;
+ _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
char **i;
int r;
size_t max_i = 0;
assert(bus);
- r = sd_bus_list_names(bus, &l);
+ r = sd_bus_list_names(bus, &acquired, &activatable);
if (r < 0) {
log_error("Failed to list names: %s", strerror(-r));
return r;
@@ -67,9 +67,13 @@ static int list_bus_names(sd_bus *bus, char **argv) {
pager_open_if_enabled();
- strv_sort(l);
+ strv_sort(acquired);
+ strv_sort(activatable);
- STRV_FOREACH(i, l)
+ STRV_FOREACH(i, acquired)
+ max_i = MAX(max_i, strlen(*i));
+
+ STRV_FOREACH(i, activatable)
max_i = MAX(max_i, strlen(*i));
printf("%-*s %*s %-*s %-*s %-*s",
@@ -80,7 +84,24 @@ static int list_bus_names(sd_bus *bus, char **argv) {
else
putchar('\n');
- STRV_FOREACH(i, l) {
+ STRV_FOREACH(i, activatable) {
+
+ /* Skip the bus driver */
+ if (streq(*i, "org.freedesktop.DBus"))
+ continue;
+
+ if (strv_contains(acquired, *i))
+ continue;
+
+ printf("%-*s", (int) max_i, *i);
+ printf(" - - - (activation) ");
+ if (arg_no_machine)
+ putchar('\n');
+ else
+ puts(" -");
+ }
+
+ STRV_FOREACH(i, acquired) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
sd_id128_t mid;
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index a993e12f7e..1c0d12a0cc 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -235,7 +235,7 @@ int sd_bus_message_rewind(sd_bus_message *m, int complete);
int sd_bus_get_unique_name(sd_bus *bus, const char **unique);
int sd_bus_request_name(sd_bus *bus, const char *name, unsigned flags);
int sd_bus_release_name(sd_bus *bus, const char *name);
-int sd_bus_list_names(sd_bus *bus, char ***l); /* free the results */
+int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */
int sd_bus_get_owner(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */
int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);