summaryrefslogtreecommitdiff
path: root/ipc/mach_msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/mach_msg.c')
-rw-r--r--ipc/mach_msg.c457
1 files changed, 0 insertions, 457 deletions
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
index 5824d8d..31ecf89 100644
--- a/ipc/mach_msg.c
+++ b/ipc/mach_msg.c
@@ -1776,460 +1776,3 @@ mach_msg_interrupt(thread)
return TRUE;
}
#endif /* CONTINUATIONS */
-
-#if MACH_IPC_COMPAT
-
-/*
- * Routine: msg_return_translate
- * Purpose:
- * Translate from new error code to old error code.
- */
-
-msg_return_t
-msg_return_translate(mr)
- mach_msg_return_t mr;
-{
- switch (mr &~ MACH_MSG_MASK) {
- case MACH_MSG_SUCCESS:
- return 0; /* SEND_SUCCESS/RCV_SUCCESS/RPC_SUCCESS */
-
- case MACH_SEND_NO_BUFFER:
- case MACH_SEND_NO_NOTIFY:
- printf("msg_return_translate: %x -> interrupted\n", mr);
- return SEND_INTERRUPTED;
-
- case MACH_SEND_MSG_TOO_SMALL:
- return SEND_MSG_TOO_SMALL;
- case MACH_SEND_INVALID_DATA:
- case MACH_SEND_INVALID_MEMORY:
- return SEND_INVALID_MEMORY;
- case MACH_SEND_TIMED_OUT:
- return SEND_TIMED_OUT;
- case MACH_SEND_INTERRUPTED:
- return SEND_INTERRUPTED;
- case MACH_SEND_INVALID_DEST:
- case MACH_SEND_INVALID_REPLY:
- case MACH_SEND_INVALID_RIGHT:
- case MACH_SEND_INVALID_TYPE:
- return SEND_INVALID_PORT;
- case MACH_SEND_WILL_NOTIFY:
- return SEND_WILL_NOTIFY;
- case MACH_SEND_NOTIFY_IN_PROGRESS:
- return SEND_NOTIFY_IN_PROGRESS;
-
- case MACH_RCV_INVALID_NAME:
- case MACH_RCV_IN_SET:
- case MACH_RCV_PORT_DIED:
- return RCV_INVALID_PORT;
- case MACH_RCV_TOO_LARGE:
- return RCV_TOO_LARGE;
- case MACH_RCV_TIMED_OUT:
- return RCV_TIMED_OUT;
- case MACH_RCV_INTERRUPTED:
- return RCV_INTERRUPTED;
- case MACH_RCV_PORT_CHANGED:
- return RCV_PORT_CHANGE;
- case MACH_RCV_INVALID_DATA:
- return RCV_INVALID_MEMORY;
-
- case MACH_SEND_IN_PROGRESS:
- case MACH_SEND_INVALID_NOTIFY:
- case MACH_SEND_INVALID_HEADER:
- case MACH_RCV_IN_PROGRESS:
- case MACH_RCV_INVALID_NOTIFY:
- case MACH_RCV_HEADER_ERROR:
- case MACH_RCV_BODY_ERROR:
- default:
-#if MACH_ASSERT
- assert(!"msg_return_translate");
-#else
- panic("msg_return_translate");
-#endif
- }
-}
-
-/*
- * Routine: msg_send_trap [mach trap]
- * Purpose:
- * Send a message.
- * Conditions:
- * Nothing locked.
- * Returns:
- */
-
-msg_return_t
-msg_send_trap(msg, option, send_size, time_out)
- msg_header_t *msg;
- msg_option_t option;
- msg_size_t send_size;
- msg_timeout_t time_out;
-{
- ipc_space_t space = current_space();
- vm_map_t map = current_map();
- ipc_kmsg_t kmsg;
- mach_msg_return_t mr;
-
- send_size = (send_size + 3) & ~3; /* round up */
-
- if (send_size > MSG_SIZE_MAX)
- return SEND_MSG_TOO_LARGE;
-
- mr = ipc_kmsg_get((mach_msg_header_t *) msg,
- (mach_msg_size_t) send_size,
- &kmsg);
- if (mr != MACH_MSG_SUCCESS)
- return msg_return_translate(mr);
-
- mr = ipc_kmsg_copyin_compat(kmsg, space, map);
- if (mr != MACH_MSG_SUCCESS) {
- ikm_free(kmsg);
- return msg_return_translate(mr);
- }
-
- if (option & SEND_NOTIFY) {
- mr = ipc_mqueue_send(kmsg, MACH_SEND_TIMEOUT,
- ((option & SEND_TIMEOUT) ?
- (mach_msg_timeout_t) time_out :
- MACH_MSG_TIMEOUT_NONE));
- if (mr == MACH_SEND_TIMED_OUT) {
- ipc_port_t dest = (ipc_port_t)
- kmsg->ikm_header.msgh_remote_port;
-
- mr = ipc_marequest_create(space, dest, MACH_PORT_NULL,
- &kmsg->ikm_marequest);
- if (mr == MACH_MSG_SUCCESS) {
- ipc_mqueue_send_always(kmsg);
- return SEND_WILL_NOTIFY;
- }
- }
- } else
- mr = ipc_mqueue_send(kmsg,
- ((option & SEND_TIMEOUT) ?
- MACH_SEND_TIMEOUT :
- MACH_MSG_OPTION_NONE),
- (mach_msg_timeout_t) time_out);
-
- if (mr != MACH_MSG_SUCCESS)
- ipc_kmsg_destroy(kmsg);
-
- return msg_return_translate(mr);
-}
-
-/*
- * Routine: msg_receive_trap [mach trap]
- * Purpose:
- * Receive a message.
- * Conditions:
- * Nothing locked.
- * Returns:
- */
-
-msg_return_t
-msg_receive_trap(msg, option, rcv_size, rcv_name, time_out)
- msg_header_t *msg;
- msg_option_t option;
- msg_size_t rcv_size;
- port_name_t rcv_name;
- msg_timeout_t time_out;
-{
- ipc_thread_t self;
- ipc_space_t space = current_space();
- vm_map_t map = current_map();
- ipc_object_t object;
- ipc_mqueue_t mqueue;
- ipc_kmsg_t kmsg;
- mach_port_seqno_t seqno;
- mach_msg_return_t mr;
-
- mr = ipc_mqueue_copyin(space, (mach_port_t) rcv_name,
- &mqueue, &object);
- if (mr != MACH_MSG_SUCCESS)
- return msg_return_translate(mr);
- /* hold ref for object; mqueue is locked */
-
-#ifdef CONTINUATIONS
- /*
- * ipc_mqueue_receive may not return, because if we block
- * then our kernel stack may be discarded. So we save
- * state here for msg_receive_continue to pick up.
- */
-
- self = current_thread();
- self->ith_msg = (mach_msg_header_t *) msg;
- self->ith_option = (mach_msg_option_t) option;
- self->ith_rcv_size = (mach_msg_size_t) rcv_size;
- self->ith_timeout = (mach_msg_timeout_t) time_out;
- self->ith_object = object;
- self->ith_mqueue = mqueue;
-#endif /* CONTINUATIONS */
-
- mr = ipc_mqueue_receive(mqueue,
- (option & RCV_TIMEOUT) ?
- MACH_RCV_TIMEOUT : MACH_MSG_OPTION_NONE,
- (mach_msg_size_t) rcv_size,
- (mach_msg_timeout_t) time_out,
- FALSE, msg_receive_continue,
- &kmsg, &seqno);
- /* mqueue is unlocked */
- ipc_object_release(object);
- if (mr != MACH_MSG_SUCCESS) {
- if (mr == MACH_RCV_TOO_LARGE) {
- msg_size_t real_size =
- (msg_size_t) (mach_msg_size_t) kmsg;
-
- assert(real_size > rcv_size);
-
- (void) copyout((vm_offset_t) &real_size,
- (vm_offset_t) &msg->msg_size,
- sizeof(msg_size_t));
- }
-
- return msg_return_translate(mr);
- }
-
- assert(kmsg->ikm_header.msgh_size <= (mach_msg_size_t) rcv_size);
-
- mr = ipc_kmsg_copyout_compat(kmsg, space, map);
- assert(mr == MACH_MSG_SUCCESS);
-
- mr = ipc_kmsg_put((mach_msg_header_t *) msg, kmsg,
- kmsg->ikm_header.msgh_size);
- return msg_return_translate(mr);
-}
-
-/*
- * Routine: msg_rpc_trap [mach trap]
- * Purpose:
- * Send and receive a message.
- * Conditions:
- * Nothing locked.
- * Returns:
- */
-
-msg_return_t
-msg_rpc_trap(msg, option, send_size, rcv_size, send_timeout, rcv_timeout)
- msg_header_t *msg;
- msg_option_t option;
- msg_size_t send_size;
- msg_size_t rcv_size;
- msg_timeout_t send_timeout;
- msg_timeout_t rcv_timeout;
-{
- ipc_thread_t self;
- ipc_space_t space = current_space();
- vm_map_t map = current_map();
- ipc_port_t reply;
- ipc_pset_t pset;
- ipc_mqueue_t mqueue;
- ipc_kmsg_t kmsg;
- mach_port_seqno_t seqno;
- mach_msg_return_t mr;
-
- /*
- * Instead of using msg_send_trap and msg_receive_trap,
- * we implement msg_rpc_trap directly. The difference
- * is how the reply port is handled. Instead of using
- * ipc_mqueue_copyin, we save a reference for the reply
- * port carried in the sent message. For example,
- * consider a rename kernel call which changes the name
- * of the call's own reply port. This is the behaviour
- * of the Mach 2.5 msg_rpc_trap.
- */
-
- send_size = (send_size + 3) & ~3; /* round up */
-
- if (send_size > MSG_SIZE_MAX)
- return SEND_MSG_TOO_LARGE;
-
- mr = ipc_kmsg_get((mach_msg_header_t *) msg,
- (mach_msg_size_t) send_size,
- &kmsg);
- if (mr != MACH_MSG_SUCCESS)
- return msg_return_translate(mr);
-
- mr = ipc_kmsg_copyin_compat(kmsg, space, map);
- if (mr != MACH_MSG_SUCCESS) {
- ikm_free(kmsg);
- return msg_return_translate(mr);
- }
-
- reply = (ipc_port_t) kmsg->ikm_header.msgh_local_port;
- if (IP_VALID(reply))
- ipc_port_reference(reply);
-
- if (option & SEND_NOTIFY) {
- mr = ipc_mqueue_send(kmsg, MACH_SEND_TIMEOUT,
- ((option & SEND_TIMEOUT) ?
- (mach_msg_timeout_t) send_timeout :
- MACH_MSG_TIMEOUT_NONE));
- if (mr == MACH_SEND_TIMED_OUT) {
- ipc_port_t dest = (ipc_port_t)
- kmsg->ikm_header.msgh_remote_port;
-
- mr = ipc_marequest_create(space, dest, MACH_PORT_NULL,
- &kmsg->ikm_marequest);
- if (mr == MACH_MSG_SUCCESS) {
- ipc_mqueue_send_always(kmsg);
- if (IP_VALID(reply))
- ipc_port_release(reply);
- return SEND_WILL_NOTIFY;
- }
- }
- } else
- mr = ipc_mqueue_send(kmsg,
- ((option & SEND_TIMEOUT) ?
- MACH_SEND_TIMEOUT :
- MACH_MSG_OPTION_NONE),
- (mach_msg_timeout_t) send_timeout);
-
- if (mr != MACH_MSG_SUCCESS) {
- ipc_kmsg_destroy(kmsg);
- if (IP_VALID(reply))
- ipc_port_release(reply);
- return msg_return_translate(mr);
- }
-
- if (!IP_VALID(reply))
- return RCV_INVALID_PORT;
-
- ip_lock(reply);
- if (reply->ip_receiver != space) {
- ip_release(reply);
- ip_check_unlock(reply);
- return RCV_INVALID_PORT;
- }
-
- assert(ip_active(reply));
- pset = reply->ip_pset;
-
- if (pset != IPS_NULL) {
- ips_lock(pset);
- if (ips_active(pset)) {
- ips_unlock(pset);
- ip_release(reply);
- ip_unlock(reply);
- return RCV_INVALID_PORT;
- }
-
- ipc_pset_remove(pset, reply);
- ips_check_unlock(pset);
- assert(reply->ip_pset == IPS_NULL);
- }
-
- mqueue = &reply->ip_messages;
- imq_lock(mqueue);
- ip_unlock(reply);
-
-#ifdef CONTINUATIONS
- /*
- * ipc_mqueue_receive may not return, because if we block
- * then our kernel stack may be discarded. So we save
- * state here for msg_receive_continue to pick up.
- */
-
- self = current_thread();
- self->ith_msg = (mach_msg_header_t *) msg;
- self->ith_option = (mach_msg_option_t) option;
- self->ith_rcv_size = (mach_msg_size_t) rcv_size;
- self->ith_timeout = (mach_msg_timeout_t) rcv_timeout;
- self->ith_object = (ipc_object_t) reply;
- self->ith_mqueue = mqueue;
-#endif /* CONTINUATIONS */
-
- mr = ipc_mqueue_receive(mqueue,
- (option & RCV_TIMEOUT) ?
- MACH_RCV_TIMEOUT : MACH_MSG_OPTION_NONE,
- (mach_msg_size_t) rcv_size,
- (mach_msg_timeout_t) rcv_timeout,
- FALSE, msg_receive_continue,
- &kmsg, &seqno);
- /* mqueue is unlocked */
- ipc_port_release(reply);
- if (mr != MACH_MSG_SUCCESS) {
- if (mr == MACH_RCV_TOO_LARGE) {
- msg_size_t real_size =
- (msg_size_t) (mach_msg_size_t) kmsg;
-
- assert(real_size > rcv_size);
-
- (void) copyout((vm_offset_t) &real_size,
- (vm_offset_t) &msg->msg_size,
- sizeof(msg_size_t));
- }
-
- return msg_return_translate(mr);
- }
-
- assert(kmsg->ikm_header.msgh_size <= (mach_msg_size_t) rcv_size);
-
- mr = ipc_kmsg_copyout_compat(kmsg, space, map);
- assert(mr == MACH_MSG_SUCCESS);
-
- mr = ipc_kmsg_put((mach_msg_header_t *) msg,
- kmsg, kmsg->ikm_header.msgh_size);
- return msg_return_translate(mr);
-}
-
-#ifdef CONTINUATIONS
-/*
- * Routine: msg_receive_continue
- * Purpose:
- * Continue after blocking for a message.
- * Conditions:
- * Nothing locked. We are running on a new kernel stack,
- * with the receive state saved in the thread. From here
- * control goes back to user space.
- */
-
-void
-msg_receive_continue()
-{
- ipc_thread_t self = current_thread();
- msg_header_t *msg = (msg_header_t *) self->ith_msg;
- msg_option_t option = (msg_option_t) self->ith_option;
- msg_size_t rcv_size = (msg_size_t) self->ith_rcv_size;
- msg_timeout_t time_out = (msg_timeout_t) self->ith_timeout;
- ipc_object_t object = self->ith_object;
- ipc_mqueue_t mqueue = self->ith_mqueue;
- ipc_kmsg_t kmsg;
- mach_port_seqno_t seqno;
- mach_msg_return_t mr;
-
- mr = ipc_mqueue_receive(mqueue,
- (option & RCV_TIMEOUT) ?
- MACH_RCV_TIMEOUT : MACH_MSG_OPTION_NONE,
- (mach_msg_size_t) rcv_size,
- (mach_msg_timeout_t) time_out,
- TRUE, msg_receive_continue,
- &kmsg, &seqno);
- /* mqueue is unlocked */
- ipc_object_release(object);
- if (mr != MACH_MSG_SUCCESS) {
- if (mr == MACH_RCV_TOO_LARGE) {
- msg_size_t real_size =
- (msg_size_t) (mach_msg_size_t) kmsg;
-
- assert(real_size > rcv_size);
-
- (void) copyout((vm_offset_t) &real_size,
- (vm_offset_t) &msg->msg_size,
- sizeof(msg_size_t));
- }
-
- thread_syscall_return(msg_return_translate(mr));
- /*NOTREACHED*/
- }
-
- assert(kmsg->ikm_header.msgh_size <= (mach_msg_size_t) rcv_size);
-
- mr = ipc_kmsg_copyout_compat(kmsg, current_space(), current_map());
- assert(mr == MACH_MSG_SUCCESS);
-
- mr = ipc_kmsg_put((mach_msg_header_t *) msg, kmsg,
- kmsg->ikm_header.msgh_size);
- thread_syscall_return(msg_return_translate(mr));
- /*NOTREACHED*/
-}
-#endif /* CONTINUATIONS */
-
-#endif /* MACH_IPC_COMPAT */