+ int error;
+ int result = 0;
+ kern_return_t kr;
+ ipc_entry_t entry;
+ ipc_mqueue_t mqueue;
+
+ kr = ipc_right_lookup_read(space, name, &entry);
+ if (kr == KERN_SUCCESS) {
+ /* space is read-locked and active */
+
+ if (entry->ie_bits & MACH_PORT_TYPE_PORT_SET) {
+ ipc_pset_t pset;
+
+ __IGNORE_WCASTALIGN(pset = (ipc_pset_t)entry->ie_object);
+ mqueue = &pset->ips_messages;
+ ips_reference(pset);
+
+ imq_lock(mqueue);
+ kn->kn_ptr.p_mqueue = mqueue;
+
+ /*
+ * Bind the portset wait queue directly to knote/kqueue.
+ * This allows us to just use wait_queue foo to effect a wakeup,
+ * rather than having to call knote() from the Mach code on each
+ * message. We still attach the knote to the mqueue klist for
+ * NOTE_REVOKE purposes only.
+ */
+ error = knote_link_waitq(kn, &mqueue->imq_wait_queue, &wq_link_id);
+ if (!error) {
+ KNOTE_ATTACH(&mqueue->imq_klist, kn);
+ imq_unlock(mqueue);
+
+ }
+ else {
+ kn->kn_ptr.p_mqueue = IMQ_NULL;
+ imq_unlock(mqueue);
+ ips_release(pset);
+ }
+
+ is_read_unlock(space);
+
+ /*
+ * linked knotes are marked stay-active and therefore don't
+ * need an indication of their fired state to be returned
+ * from the attach operation.
+ */
+
+ } else if (entry->ie_bits & MACH_PORT_TYPE_RECEIVE) {
+ ipc_port_t port;
+
+ __IGNORE_WCASTALIGN(port = (ipc_port_t)entry->ie_object);
+ mqueue = &port->ip_messages;
+ ip_reference(port);
+
+ /*
+ * attach knote to port and determine result
+ * If the filter requested direct message receipt,
+ * we may need to adjust the qos of the knote to
+ * reflect the requested and override qos of the
+ * first message in the queue.
+ */
+ imq_lock(mqueue);
+ kn->kn_ptr.p_mqueue = mqueue;
+ KNOTE_ATTACH(&mqueue->imq_klist, kn);
+ if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+ int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
+ if (kn->kn_sfflags & MACH_RCV_MSG)
+ knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+ sync_qos_override_index);
+ result = 1;
+ }
+ imq_unlock(mqueue);
+
+ is_read_unlock(space);
+ error = 0;
+ } else {
+ is_read_unlock(space);
+ error = ENOTSUP;
+ }
+ } else {
+ error = ENOENT;
+ }
+
+ waitq_link_release(wq_link_id);
+
+ /* bail out on errors */
+ if (error) {
+ kn->kn_flags |= EV_ERROR;
+ kn->kn_data = error;
+ return 0;
+ }