summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/bus-control.c
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2013-11-30 13:31:04 +0100
committerDaniel Mack <zonque@gmail.com>2013-11-30 13:31:04 +0100
commit1d0e3c98840d89ec0a4dc521663320632a8516e7 (patch)
treec3e769f19aa584a9e0eccf4ee160498a9b5dfc40 /src/libsystemd-bus/bus-control.c
parent683fc3a4480645fd2201e5f7c2e1fee277b3eaa0 (diff)
libsystemd-bus: catch up with latest kdbus changes
The name list and query functions now work differently in kdbus, as the result is stored in the connection's pool, rather than being copied back through the ioctl buffer. That also safes us some logic, as we don't have to resize the communication buffer in a loop with growing buffer sizes. Due to this, KDBUS_CMD_MSG_RELEASE was renamed to KDBUS_CMD_FREE, as it is now used outside the message logic as well.
Diffstat (limited to 'src/libsystemd-bus/bus-control.c')
-rw-r--r--src/libsystemd-bus/bus-control.c95
1 files changed, 35 insertions, 60 deletions
diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index a0eeb305da..1d1f6d0f39 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -174,36 +174,23 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***l) {
assert_return(!bus_pid_changed(bus), -ECHILD);
if (bus->is_kernel) {
- _cleanup_free_ struct kdbus_cmd_names *names = NULL;
+ _cleanup_free_ struct kdbus_cmd_name_list *cmd = NULL;
+ struct kdbus_name_list *name_list;
struct kdbus_cmd_name *name;
- size_t size;
- /* assume 8k size first. If that doesn't suffice, kdbus will tell us
- * how big the buffer needs to be. */
- size = 8192;
-
- for(;;) {
- names = realloc(names, size);
- if (!names)
- return -ENOMEM;
-
- names->size = size;
- names->flags = KDBUS_NAME_LIST_UNIQUE_NAMES;
+ cmd = malloc0(sizeof(struct kdbus_cmd_name_list *));
+ if (!cmd)
+ return -ENOMEM;
- r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, names);
- if (r < 0) {
- if (errno == ENOBUFS && size != names->size) {
- size = names->size;
- continue;
- }
+ cmd->flags = KDBUS_NAME_LIST_UNIQUE_NAMES;
- return -errno;
- }
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, cmd);
+ if (r < 0)
+ return -errno;
- break;
- }
+ name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
- KDBUS_PART_FOREACH(name, names, names) {
+ KDBUS_PART_FOREACH(name, name_list, names) {
char *n;
if (name->size > sizeof(*name))
@@ -216,6 +203,10 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***l) {
return -ENOMEM;
}
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset);
+ if (r < 0)
+ return -errno;
+
*l = x;
} else {
r = sd_bus_call_method(
@@ -587,7 +578,7 @@ static int add_name_change_match(sd_bus *bus,
return 0;
}
-static int kdbus_name_query(
+static int kdbus_name_info(
sd_bus *bus,
const char *name,
uint64_t mask,
@@ -596,52 +587,32 @@ static int kdbus_name_query(
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+ _cleanup_free_ struct kdbus_cmd_name_info *cmd = NULL;
_cleanup_free_ char *unique = NULL;
- struct kdbus_cmd_name_info *name_info = NULL;
+ struct kdbus_name_info *name_info;
struct kdbus_item *item;
uint64_t attach_flags, m;
- size_t slen, size;
+ size_t size;
int r;
r = kdbus_translate_attach_flags(mask, &attach_flags);
if (r < 0)
return r;
- slen = strlen(name) + 1;
-
- /*
- * The structure is used for both directions. Start with 8k buffer size and
- * expand to the size kdbus reports in case we fail.
- */
- size = slen + 8192;
-
- for(;;) {
- name_info = realloc(name_info, size);
- if (!name_info)
- return -ENOMEM;
-
- memset(name_info, 0, size);
-
- name_info->size = size;
- name_info->attach_flags = attach_flags;
-
- item = name_info->items;
- item->type = KDBUS_NAME_INFO_ITEM_NAME;
- item->size = KDBUS_ITEM_SIZE(slen);
- strcpy(item->str, name);
+ size = sizeof(struct kdbus_cmd_name_info) + strlen(name) + 1;
+ cmd = malloc0(size);
+ if (!cmd)
+ return -ENOMEM;
- r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_QUERY, name_info);
- if (r < 0) {
- if (errno == ENOBUFS && size != name_info->size) {
- size = name_info->size;
- continue;
- }
+ cmd ->size = size;
+ cmd->attach_flags = attach_flags;
+ strcpy(cmd->name, name);
- return -errno;
- }
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_INFO, cmd);
+ if (r < 0)
+ return -errno;
- break;
- }
+ name_info = (struct kdbus_name_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
asprintf(&unique, ":1.%llu", (unsigned long long) name_info->id);
@@ -756,6 +727,10 @@ static int kdbus_name_query(
}
}
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset);
+ if (r < 0)
+ return -errno;
+
if (creds) {
*creds = c;
c = NULL;
@@ -784,7 +759,7 @@ _public_ int sd_bus_get_owner(
assert_return(!bus_pid_changed(bus), -ECHILD);
if (bus->is_kernel)
- return kdbus_name_query(bus, name, mask, owner, creds);
+ return kdbus_name_info(bus, name, mask, owner, creds);
return sd_bus_get_owner_dbus(bus, name, mask, owner, creds);
}