[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