&name, (ipc_object_t *) &pset);
if (kr != KERN_SUCCESS)
return kr;
- /* pset is locked */
+ /* pset and space are locked */
pset->ips_local_name = name;
ipc_mqueue_init(&pset->ips_messages, TRUE /* set */);
+ is_write_unlock(space);
*namep = name;
*psetp = pset;
* provided, just force a MACH_RCV_TOO_LARGE to detect the
* name of the port and sizeof the waiting message.
*/
- option = kn->kn_sfflags & (MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_TRAILER_MASK);
+ option = kn->kn_sfflags & (MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_LARGE_IDENTITY|
+ MACH_RCV_TRAILER_MASK|MACH_RCV_VOUCHER);
if (option & MACH_RCV_MSG) {
self->ith_msg_addr = (mach_vm_address_t) kn->kn_ext[0];
size = (mach_msg_size_t)kn->kn_ext[1];
self->ith_receiver_name = MACH_PORT_NULL;
self->ith_continuation = NULL;
option |= MACH_RCV_TIMEOUT; // never wait
- assert((self->ith_state = MACH_RCV_IN_PROGRESS) == MACH_RCV_IN_PROGRESS);
+ self->ith_state = MACH_RCV_IN_PROGRESS;
wresult = ipc_mqueue_receive_on_thread(
&pset->ips_messages,
* the results in the fflags field.
*/
assert(option & MACH_RCV_MSG);
- kn->kn_data = MACH_PORT_NULL;
kn->kn_ext[1] = self->ith_msize;
+ kn->kn_data = MACH_PORT_NULL;
kn->kn_fflags = mach_msg_receive_results();
/* kmsg and pset reference consumed */
+
+ /*
+ * if the user asked for the identity of ports containing a
+ * a too-large message, return it in the data field (as we
+ * do for messages we didn't try to receive).
+ */
+ if ((kn->kn_fflags == MACH_RCV_TOO_LARGE) &&
+ (option & MACH_RCV_LARGE_IDENTITY))
+ kn->kn_data = self->ith_receiver_name;
+
return 1;
}
case EVENT_REGISTER:
kn->kn_sfflags = kev->fflags;
kn->kn_sdata = kev->data;
+ kn->kn_ext[0] = kev->ext[0];
+ kn->kn_ext[1] = kev->ext[1];
break;
case EVENT_PROCESS:
*kev = kn->kn_kevent;
ipc_pset_t pset = kn->kn_ptr.p_pset;
ipc_mqueue_t set_mq = &pset->ips_messages;
- return (ipc_mqueue_peek(set_mq));
+ return (ipc_mqueue_set_peek(set_mq));
}