From f08838da225678269945868a71bbdc79de967e1d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Apr 2013 03:08:14 +0200 Subject: [PATCH] bus: implement basic name registration with kdbus --- src/libsystemd-bus/bus-control.c | 110 ++++++++++++++++++--------- src/libsystemd-bus/bus-kernel.c | 9 ++- src/libsystemd-bus/sd-bus.c | 2 +- src/libsystemd-bus/test-bus-kernel.c | 9 +++ 4 files changed, 93 insertions(+), 37 deletions(-) diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index a0abccf1d..7c139cfd3 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -54,26 +54,46 @@ int sd_bus_request_name(sd_bus *bus, const char *name, int flags) { return -EINVAL; if (!name) return -EINVAL; + if (!bus->bus_client) + return -EINVAL; - r = sd_bus_call_method( - bus, - "org.freedesktop.DBus", - "/", - "org.freedesktop.DBus", - "RequestName", - NULL, - &reply, - "su", - name, - flags); - if (r < 0) - return r; - - r = sd_bus_message_read(reply, "u", &ret); - if (r < 0) - return r; - - return ret; + if (bus->is_kernel) { + struct kdbus_cmd_name *n; + size_t l; + + l = strlen(name); + n = alloca(offsetof(struct kdbus_cmd_name, name) + l + 1); + n->size = offsetof(struct kdbus_cmd_name, name) + l + 1; + n->flags = flags; + n->id = 0; + memcpy(n->name, name, l+1); + + r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n); + if (r < 0) + return -errno; + + return n->flags; + } else { + r = sd_bus_call_method( + bus, + "org.freedesktop.DBus", + "/", + "org.freedesktop.DBus", + "RequestName", + NULL, + &reply, + "su", + name, + flags); + if (r < 0) + return r; + + r = sd_bus_message_read(reply, "u", &ret); + if (r < 0) + return r; + + return ret; + } } int sd_bus_release_name(sd_bus *bus, const char *name) { @@ -85,23 +105,43 @@ int sd_bus_release_name(sd_bus *bus, const char *name) { return -EINVAL; if (!name) return -EINVAL; + if (!bus->bus_client) + return -EINVAL; - r = sd_bus_call_method( - bus, - "org.freedesktop.DBus", - "/", - "org.freedesktop.DBus", - "ReleaseName", - NULL, - &reply, - "s", - name); - if (r < 0) - return r; - - r = sd_bus_message_read(reply, "u", &ret); - if (r < 0) - return r; + if (bus->is_kernel) { + struct kdbus_cmd_name *n; + size_t l; + + l = strlen(name); + n = alloca(offsetof(struct kdbus_cmd_name, name) + l + 1); + n->size = offsetof(struct kdbus_cmd_name, name) + l + 1; + n->flags = 0; + n->id = 0; + memcpy(n->name, name, l+1); + + r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n); + if (r < 0) + return -errno; + + return n->flags; + } else { + r = sd_bus_call_method( + bus, + "org.freedesktop.DBus", + "/", + "org.freedesktop.DBus", + "ReleaseName", + NULL, + &reply, + "s", + name); + if (r < 0) + return r; + + r = sd_bus_message_read(reply, "u", &ret); + if (r < 0) + return r; + } return ret; } diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index add0bc11d..9d0be7a19 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -158,6 +158,9 @@ int bus_kernel_take_fd(sd_bus *b) { assert(b); + if (b->is_server) + return -EINVAL; + r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello); if (r < 0) return -errno; @@ -166,6 +169,7 @@ int bus_kernel_take_fd(sd_bus *b) { return -ENOMEM; b->is_kernel = true; + b->bus_client = true; r = bus_start_running(b); if (r < 0) @@ -180,6 +184,9 @@ int bus_kernel_connect(sd_bus *b) { assert(b->output_fd < 0); assert(b->kernel); + if (b->is_server) + return -EINVAL; + b->input_fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC); if (b->input_fd < 0) return -errno; @@ -339,7 +346,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) { struct kdbus_msg *k; - size_t sz = 128; + size_t sz = 1024; int r; assert(bus); diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 2424ee144..f40958a26 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -280,7 +280,7 @@ static int bus_send_hello(sd_bus *bus) { int bus_start_running(sd_bus *bus) { assert(bus); - if (bus->bus_client) { + if (bus->bus_client && !bus->is_kernel) { bus->state = BUS_HELLO; return 1; } diff --git a/src/libsystemd-bus/test-bus-kernel.c b/src/libsystemd-bus/test-bus-kernel.c index d0f8f94db..f519bf61c 100644 --- a/src/libsystemd-bus/test-bus-kernel.c +++ b/src/libsystemd-bus/test-bus-kernel.c @@ -85,6 +85,15 @@ int main(int argc, char *argv[]) { assert_se(r >= 0); assert_se(streq(the_string, "I am a string")); + r = sd_bus_request_name(a, "net.0pointer.foobar", 0); + assert_se(r >= 0); + + r = sd_bus_release_name(a, "net.0pointer.foobar"); + assert_se(r >= 0); + + r = sd_bus_release_name(a, "net.0pointer.foobar"); + assert_se(r < 0); + sd_bus_unref(a); sd_bus_unref(b); -- 2.30.2