+ /* If the name argument is missing or is a well-known
+ * name, then add KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE}
+ * matches for it */
+
+ l = name ? strlen(name) : 0;
+
+ sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
+ offsetof(struct kdbus_item, name_change) +
+ offsetof(struct kdbus_notify_name_change, name) +
+ l+1);
+
+ m = alloca0(sz);
+ m->size = sz;
+ m->cookie = cookie;
+ m->src_id = KDBUS_SRC_ID_KERNEL;
+
+ item = m->items;
+ item->size =
+ offsetof(struct kdbus_item, name_change) +
+ offsetof(struct kdbus_notify_name_change, name) +
+ l+1;
+
+ item->name_change.old_id = old_owner_id;
+ item->name_change.new_id = new_owner_id;
+
+ if (name)
+ strcpy(item->name_change.name, name);
+
+ /* If the old name is unset or empty, then
+ * this can match against added names */
+ if (!old_owner || old_owner[0] == 0) {
+ item->type = KDBUS_MATCH_NAME_ADD;
+
+ r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
+ if (r < 0)
+ return -errno;
+ }
+
+ /* If the new name is unset or empty, then
+ * this can match against removed names */
+ if (!new_owner || new_owner[0] == 0) {
+ item->type = KDBUS_MATCH_NAME_REMOVE;
+
+ r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
+ if (r < 0)
+ return -errno;
+ }
+
+ /* If the neither name is explicitly set to
+ * the empty string, then this can match
+ * agains changed names */
+ if (!(old_owner && old_owner[0] == 0) &&
+ !(new_owner && new_owner[0] == 0)) {
+ item->type = KDBUS_MATCH_NAME_CHANGE;
+
+ r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
+ if (r < 0)
+ return -errno;
+ }
+ }
+
+ if (is_name_id != 0) {
+ struct kdbus_cmd_match *m;
+ uint64_t sz;
+
+ /* If the name argument is missing or is a unique
+ * name, then add KDBUS_MATCH_ID_{ADD,REMOVE} matches
+ * for it */
+
+ sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
+ offsetof(struct kdbus_item, id_change) +
+ sizeof(struct kdbus_notify_id_change));
+
+ m = alloca0(sz);
+ m->size = sz;
+ m->cookie = cookie;
+ m->src_id = KDBUS_SRC_ID_KERNEL;
+
+ item = m->items;
+ item->size = offsetof(struct kdbus_item, id_change) + sizeof(struct kdbus_notify_id_change);
+ item->id_change.id = name_id;
+
+ /* If the old name is unset or empty, then this can
+ * match against added ids */
+ if (!old_owner || old_owner[0] == 0) {
+ item->type = KDBUS_MATCH_ID_ADD;
+
+ r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
+ if (r < 0)
+ return -errno;
+ }
+
+ /* If thew new name is unset or empty, then this can
+ match against removed ids */
+ if (!new_owner || new_owner[0] == 0) {
+ item->type = KDBUS_MATCH_ID_REMOVE;