+ * Asks kdbus for list of connections being in the queue to own
+ * given well-known name. The list includes the owner of the name on the
+ * first position.
+ */
+dbus_bool_t kdbus_list_queued (DBusConnection *connection, DBusList **return_list,
+ const char *name, DBusError *error)
+{
+ int fd;
+ dbus_bool_t ret_val = FALSE;
+ int name_length;
+ struct kdbus_cmd_conn_info *pCmd;
+ __u64 cmd_size;
+ DBusTransport *transport = dbus_connection_get_transport(connection);
+ struct kdbus_name_list *name_list;
+ struct kdbus_cmd_name *owner;
+
+ _dbus_assert (*return_list == NULL);
+
+ name_length = strlen(name) + 1;
+ cmd_size = sizeof(struct kdbus_cmd_conn_info) + name_length;
+ pCmd = alloca(cmd_size);
+ if(pCmd == NULL)
+ goto out;
+ pCmd->size = cmd_size;
+ pCmd->id = 0;
+ memcpy(pCmd->name, name, name_length);
+
+ _dbus_verbose ("Asking for queued owners of %s\n", pCmd->name);
+
+ _dbus_transport_get_socket_fd(transport, &fd);
+
+ again:
+ if(ioctl(fd, KDBUS_CMD_NAME_LIST_QUEUED, pCmd))
+ {
+ if(errno == EINTR)
+ goto again;
+ else if(errno == ESRCH)
+ {
+ dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
+ "Could not get owners of name '%s': no such name", name);
+ return FALSE;
+ }
+ else
+ {
+ _dbus_verbose("kdbus error asking for queued owners list: err %d (%m)\n",errno);
+ goto out;
+ }
+ }
+
+ name_list = (struct kdbus_name_list *)((char*)dbus_transport_get_pool_pointer(transport) + pCmd->offset);
+
+ for (owner = name_list->names; (uint8_t *)(owner) < (uint8_t *)(name_list) + name_list->size; owner = KDBUS_PART_NEXT(owner))
+ {
+ char *uname = NULL;
+
+ _dbus_verbose ("Got queued owner id: %llu\n", (unsigned long long)owner->id);
+ uname = malloc(snprintf(uname, 0, ":1.%llu0", (unsigned long long)owner->id));
+ if(uname == NULL)
+ goto out;
+ sprintf(uname, ":1.%llu", (unsigned long long int)owner->id);
+ if (!_dbus_list_append (return_list, uname))
+ goto out;
+ }
+
+ ret_val = TRUE;
+
+ out:
+ if (ioctl(fd, KDBUS_CMD_FREE, &pCmd->offset) < 0)
+ {
+ if(errno == EINTR)
+ goto out;
+ _dbus_verbose("kdbus error freeing pool: %d (%m)\n", errno);
+ ret_val = FALSE;
+ }
+ if(ret_val == FALSE)
+ {
+ DBusList *link;
+
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to list queued owners of \"%s\": %s",
+ name, _dbus_strerror (errno));
+
+ link = _dbus_list_get_first_link (return_list);
+ while (link != NULL)
+ {
+ DBusList *next = _dbus_list_get_next_link (return_list, link);
+
+ if(link->data != NULL)
+ free(link->data);
+
+ _dbus_list_free_link (link);
+ link = next;
+ }
+ }
+
+ return ret_val;
+}
+
+/*