[systemd-devel] [PATCH 4/7] libsystemd-bus: add kdbus support for sd_bus_get_owner(|_pid|_uid)

Daniel Mack zonque at gmail.com
Fri Nov 15 10:32:20 PST 2013


Introduce kdbus_name_info as internal helper to make the actual ioctl()
to kdbus.
---
 src/libsystemd-bus/bus-control.c | 153 +++++++++++++++++++++++++++------------
 1 file changed, 107 insertions(+), 46 deletions(-)

diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index 562513b..28adebd 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -256,9 +256,42 @@ retry:
         return 0;
 }
 
+static int kdbus_name_info(sd_bus *b, const char *name, struct kdbus_cmd_name_info **info) {
+
+        struct kdbus_cmd_name_info *i;
+        struct kdbus_item *item;
+        size_t slen, size;
+        int r;
+
+        slen = strlen(name) + 1;
+
+        /* The structure is used for both directions. Hence, it has to be able
+         * to acommodate both the request and the reply.  */
+        size = MAX(b->name_query_min_size, ALIGN8(sizeof(*info) + KDBUS_ITEM_SIZE(slen)));
+        i = malloc0(size);
+        if (!i)
+                return -ENOMEM;
+
+        i->size = size;
+
+        item = i->items;
+        item->type = KDBUS_NAME_INFO_ITEM_NAME;
+        item->size = KDBUS_ITEM_SIZE(slen);
+        strcpy(item->str, name);
+
+        r = ioctl(sd_bus_get_fd(b), KDBUS_CMD_NAME_QUERY, i);
+        if (r < 0)
+                return -errno;
+
+        *info = i;
+
+        return 0;
+}
+
 _public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        const char *found;
+        _cleanup_free_ struct kdbus_cmd_name_info *info = NULL;
+        char *found;
         int r;
 
         assert_return(bus, -EINVAL);
@@ -266,22 +299,32 @@ _public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
         assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.DBus",
-                        "/",
-                        "org.freedesktop.DBus",
-                        "GetNameOwner",
-                        NULL,
-                        &reply,
-                        "s",
-                        name);
-        if (r < 0)
-                return r;
+        if (bus->is_kernel) {
+                r = kdbus_name_info(bus, name, &info);
+                if (r < 0)
+                        return r;
 
-        r = sd_bus_message_read(reply, "s", &found);
-        if (r < 0)
-                return r;
+                r = asprintf(&found, ":1.%llu", (unsigned long long) info->id);
+                if (r < 0)
+                        return log_oom();
+        } else {
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.DBus",
+                                "/",
+                                "org.freedesktop.DBus",
+                                "GetNameOwner",
+                                NULL,
+                                &reply,
+                                "s",
+                                name);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_read(reply, "s", &found);
+                if (r < 0)
+                        return r;
+        }
 
         if (owner) {
                 char *t;
@@ -298,6 +341,7 @@ _public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
 
 _public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_free_ struct kdbus_cmd_name_info *info = NULL;
         uint32_t u;
         int r;
 
@@ -312,22 +356,30 @@ _public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
         if (bus_pid_changed(bus))
                 return -ECHILD;
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.DBus",
-                        "/",
-                        "org.freedesktop.DBus",
-                        "GetConnectionUnixUser",
-                        NULL,
-                        &reply,
-                        "s",
-                        name);
-        if (r < 0)
-                return r;
+        if (bus->kernel) {
+                r = kdbus_name_info(bus, name, &info);
+                if (r < 0)
+                        return r;
 
-        r = sd_bus_message_read(reply, "u", &u);
-        if (r < 0)
-                return r;
+                u = info->creds.uid;
+        } else {
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.DBus",
+                                "/",
+                                "org.freedesktop.DBus",
+                                "GetConnectionUnixUser",
+                                NULL,
+                                &reply,
+                                "s",
+                                name);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_read(reply, "u", &u);
+                if (r < 0)
+                        return r;
+        }
 
         *uid = (uid_t) u;
         return 0;
@@ -335,6 +387,7 @@ _public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
 
 _public_ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_free_ struct kdbus_cmd_name_info *info = NULL;
         uint32_t u;
         int r;
 
@@ -349,22 +402,30 @@ _public_ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
         if (bus_pid_changed(bus))
                 return -ECHILD;
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.DBus",
-                        "/",
-                        "org.freedesktop.DBus",
-                        "GetConnectionUnixProcessID",
-                        NULL,
-                        &reply,
-                        "s",
-                        name);
-        if (r < 0)
-                return r;
+        if (bus->kernel) {
+                r = kdbus_name_info(bus, name, &info);
+                if (r < 0)
+                        return r;
 
-        r = sd_bus_message_read(reply, "u", &u);
-        if (r < 0)
-                return r;
+                u = info->creds.pid;
+        } else {
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.DBus",
+                                "/",
+                                "org.freedesktop.DBus",
+                                "GetConnectionUnixProcessID",
+                                NULL,
+                                &reply,
+                                "s",
+                                name);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_read(reply, "u", &u);
+                if (r < 0)
+                        return r;
+        }
 
         if (u == 0)
                 return -EIO;
-- 
1.8.4.2



More information about the systemd-devel mailing list