* Copyin a naked capability from the kernel.
*
* MACH_MSG_TYPE_MOVE_RECEIVE
- * The receiver must be ipc_space_kernel.
+ * The receiver must be ipc_space_kernel
+ * or the receive right must already be in limbo.
* Consumes the naked receive right.
* MACH_MSG_TYPE_COPY_SEND
* A naked send right must be supplied.
ip_lock(port);
assert(ip_active(port));
- assert(port->ip_receiver_name != MACH_PORT_NULL);
- assert(port->ip_receiver == ipc_space_kernel);
+ if (port->ip_destination != IP_NULL) {
+ assert(port->ip_receiver == ipc_space_kernel);
- /* relevant part of ipc_port_clear_receiver */
- ipc_port_set_mscount(port, 0);
+ /* relevant part of ipc_port_clear_receiver */
+ ipc_port_set_mscount(port, 0);
- port->ip_receiver_name = MACH_PORT_NULL;
- port->ip_destination = IP_NULL;
+ port->ip_receiver_name = MACH_PORT_NULL;
+ port->ip_destination = IP_NULL;
+ }
ip_unlock(port);
break;
}
break;
}
- case MACH_MSG_TYPE_MOVE_SEND:
+ case MACH_MSG_TYPE_MOVE_SEND: {
/* move naked send right into the message */
+ ipc_port_t port = (ipc_port_t) object;
+ assert(port->ip_srights);
break;
+ }
case MACH_MSG_TYPE_MAKE_SEND_ONCE: {
ipc_port_t port = (ipc_port_t) object;
break;
}
- case MACH_MSG_TYPE_MOVE_SEND_ONCE:
+ case MACH_MSG_TYPE_MOVE_SEND_ONCE: {
/* move naked send-once right into the message */
+ ipc_port_t port = (ipc_port_t) object;
+ assert(port->ip_sorights);
break;
+ }
default:
panic("ipc_object_copyin_from_kernel: strange rights");