diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_kmsg.c | 494 | ||||
-rw-r--r-- | ipc/ipc_kmsg.h | 9 | ||||
-rw-r--r-- | ipc/ipc_marequest.c | 36 | ||||
-rw-r--r-- | ipc/ipc_notify.c | 132 | ||||
-rw-r--r-- | ipc/ipc_notify.h | 12 | ||||
-rw-r--r-- | ipc/ipc_object.c | 325 | ||||
-rw-r--r-- | ipc/ipc_object.h | 24 | ||||
-rw-r--r-- | ipc/ipc_port.c | 239 | ||||
-rw-r--r-- | ipc/ipc_port.h | 37 | ||||
-rw-r--r-- | ipc/ipc_right.c | 618 | ||||
-rw-r--r-- | ipc/ipc_right.h | 11 | ||||
-rw-r--r-- | ipc/ipc_space.c | 32 | ||||
-rw-r--r-- | ipc/ipc_space.h | 23 | ||||
-rw-r--r-- | ipc/mach_debug.c | 8 | ||||
-rw-r--r-- | ipc/mach_msg.c | 457 | ||||
-rw-r--r-- | ipc/mach_msg.h | 6 | ||||
-rw-r--r-- | ipc/mach_port.c | 959 |
17 files changed, 0 insertions, 3422 deletions
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c index 9f207d7..e6e2932 100644 --- a/ipc/ipc_kmsg.c +++ b/ipc/ipc_kmsg.c @@ -651,13 +651,6 @@ ipc_kmsg_put_to_kernel( * notification would be sent to the named receive right, * then it isn't sent and the send-once right for the notify * port is quietly destroyed. - * - * [MACH_IPC_COMPAT] There is an atomicity problem if the - * reply port is a compat entry and dies at an inopportune - * time. This doesn't have any serious consequences - * (an observant user task might conceivably notice that - * the destination and reply ports were handled inconsistently), - * only happens in compat mode, and is extremely unlikely. * Conditions: * Nothing locked. * Returns: @@ -1225,27 +1218,7 @@ ipc_kmsg_copyin_header(msg, space, notify) kr = ipc_right_copyin(space, reply_name, reply_entry, reply_type, TRUE, &reply_port, &reply_soright); -#if MACH_IPC_COMPAT - if (kr != KERN_SUCCESS) { - assert(kr == KERN_INVALID_NAME); - - /* - * Oops. This must have been a compat entry - * and the port died after the check above. - * We should back out the copyin of dest_port, - * and report MACH_SEND_INVALID_REPLY, but - * if dest_port is alive we can't always do that. - * Punt and pretend we got IO_DEAD, skipping - * further hairy atomicity problems. - */ - - reply_port = IO_DEAD; - reply_soright = IP_NULL; - goto skip_reply_checks; - } -#else /* MACH_IPC_COMPAT */ assert(kr == KERN_SUCCESS); -#endif /* MACH_IPC_COMPAT */ if ((saved_reply != IP_NULL) && (reply_port == IO_DEAD)) { ipc_port_t dest = (ipc_port_t) dest_port; @@ -1306,15 +1279,6 @@ ipc_kmsg_copyin_header(msg, space, notify) if (IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE) ipc_entry_dealloc(space, reply_name, reply_entry); -#if MACH_IPC_COMPAT - skip_reply_checks: - /* - * We jump here if the reply entry was a compat entry - * and the port died on us. In this case, the copyin - * code already deallocated reply_entry. - */ -#endif /* MACH_IPC_COMPAT */ - if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) ipc_entry_dealloc(space, dest_name, dest_entry); @@ -2685,464 +2649,6 @@ ipc_kmsg_copyout_dest(kmsg, space) } } -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_kmsg_copyin_compat - * Purpose: - * "Copy-in" port rights and out-of-line memory - * in the message. - * - * In all failure cases, the message is left holding - * no rights or memory. However, the message buffer - * is not deallocated. If successful, the message - * contains a valid destination port. - * Conditions: - * Nothing locked. - * Returns: - * MACH_MSG_SUCCESS Successful copyin. - * MACH_SEND_INVALID_DEST Can't copyin destination port. - * MACH_SEND_INVALID_REPLY Can't copyin reply port. - * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory. - * MACH_SEND_INVALID_RIGHT Can't copyin port right in body. - * MACH_SEND_INVALID_TYPE Bad type specification. - * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data. - */ - -mach_msg_return_t -ipc_kmsg_copyin_compat(kmsg, space, map) - ipc_kmsg_t kmsg; - ipc_space_t space; - vm_map_t map; -{ - msg_header_t msg; - mach_port_t dest_name; - mach_port_t reply_name; - ipc_object_t dest, reply; - mach_msg_type_name_t dest_type, reply_type; - vm_offset_t saddr, eaddr; - boolean_t complex; - kern_return_t kr; - boolean_t use_page_lists, steal_pages; - - msg = * (msg_header_t *) &kmsg->ikm_header; - dest_name = (mach_port_t) msg.msg_remote_port; - reply_name = (mach_port_t) msg.msg_local_port; - - /* translate the destination and reply ports */ - - kr = ipc_object_copyin_header(space, dest_name, &dest, &dest_type); - if (kr != KERN_SUCCESS) - return MACH_SEND_INVALID_DEST; - - if (reply_name == MACH_PORT_NULL) { - reply = IO_NULL; - reply_type = 0; - } else { - kr = ipc_object_copyin_header(space, reply_name, - &reply, &reply_type); - if (kr != KERN_SUCCESS) { - ipc_object_destroy(dest, dest_type); - return MACH_SEND_INVALID_REPLY; - } - } - - kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(dest_type, reply_type); - kmsg->ikm_header.msgh_size = (mach_msg_size_t) msg.msg_size; - kmsg->ikm_header.msgh_remote_port = (mach_port_t) dest; - kmsg->ikm_header.msgh_local_port = (mach_port_t) reply; - kmsg->ikm_header.msgh_seqno = (mach_msg_kind_t) msg.msg_type; - kmsg->ikm_header.msgh_id = (mach_msg_id_t) msg.msg_id; - - if (msg.msg_simple) - return MACH_MSG_SUCCESS; - - complex = FALSE; - use_page_lists = ipc_kobject_vm_page_list(ip_kotype((ipc_port_t)dest)); - steal_pages = ipc_kobject_vm_page_steal(ip_kotype((ipc_port_t)dest)); - - saddr = (vm_offset_t) (&kmsg->ikm_header + 1); - eaddr = (vm_offset_t) &kmsg->ikm_header + kmsg->ikm_header.msgh_size; - - while (saddr < eaddr) { - vm_offset_t taddr = saddr; - mach_msg_type_long_t *type; - mach_msg_type_name_t name; - mach_msg_type_size_t size; - mach_msg_type_number_t number; - boolean_t is_inline, longform, dealloc, is_port; - vm_offset_t data; - vm_size_t length; - - type = (mach_msg_type_long_t *) saddr; - - if (((eaddr - saddr) < sizeof(mach_msg_type_t)) || - ((longform = ((mach_msg_type_t*)type)->msgt_longform) && - ((eaddr - saddr) < sizeof(mach_msg_type_long_t)))) { - ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0); - return MACH_SEND_MSG_TOO_SMALL; - } - - is_inline = ((mach_msg_type_t*)type)->msgt_inline; - dealloc = ((mach_msg_type_t*)type)->msgt_deallocate; - if (longform) { - /* This must be aligned */ - if ((sizeof(natural_t) > sizeof(mach_msg_type_t)) && - (is_misaligned(type))) { - saddr = ptr_align(saddr); - continue; - } - name = type->msgtl_name; - size = type->msgtl_size; - number = type->msgtl_number; - saddr += sizeof(mach_msg_type_long_t); - } else { - name = ((mach_msg_type_t*)type)->msgt_name; - size = ((mach_msg_type_t*)type)->msgt_size; - number = ((mach_msg_type_t*)type)->msgt_number; - saddr += sizeof(mach_msg_type_t); - } - - is_port = MSG_TYPE_PORT_ANY(name); - - if (is_port && (size != PORT_T_SIZE_IN_BITS)) { - ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0); - return MACH_SEND_INVALID_TYPE; - } - - /* - * New IPC says these should be zero, but old IPC - * tasks often leave them with random values. So - * we have to clear them. - */ - - ((mach_msg_type_t*)type)->msgt_unused = 0; - if (longform) { - type->msgtl_header.msgt_name = 0; - type->msgtl_header.msgt_size = 0; - type->msgtl_header.msgt_number = 0; - } - - /* padding (ptrs and ports) ? */ - if ((sizeof(natural_t) > sizeof(mach_msg_type_t)) && - ((size >> 3) == sizeof(natural_t))) - saddr = ptr_align(saddr); - - /* calculate length of data in bytes, rounding up */ - - length = ((number * size) + 7) >> 3; - - if (is_inline) { - vm_size_t amount; - - /* inline data sizes round up to int boundaries */ - - amount = (length + 3) &~ 3; - if ((eaddr - saddr) < amount) { - ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0); - return MACH_SEND_MSG_TOO_SMALL; - } - - data = saddr; - saddr += amount; - } else { - vm_offset_t addr; - - if ((eaddr - saddr) < sizeof(vm_offset_t)) { - ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0); - return MACH_SEND_MSG_TOO_SMALL; - } - - /* grab the out-of-line data */ - - addr = * (vm_offset_t *) saddr; - - if (length == 0) - data = 0; - else if (is_port) { - data = kalloc(length); - if (data == 0) - goto invalid_memory; - - if (copyinmap(map, (char *) addr, - (char *) data, length) || - (dealloc && - (vm_deallocate(map, addr, length) != - KERN_SUCCESS))) { - kfree(data, length); - goto invalid_memory; - } - } else { - vm_map_copy_t copy; - - if (use_page_lists) { - kr = vm_map_copyin_page_list(map, - addr, length, dealloc, - steal_pages, ©, FALSE); - } else { - kr = vm_map_copyin(map, addr, length, - dealloc, - ©); - } - if (kr != KERN_SUCCESS) { - invalid_memory: - ipc_kmsg_clean_partial(kmsg, taddr, - FALSE, 0); - return MACH_SEND_INVALID_MEMORY; - } - - data = (vm_offset_t) copy; - } - - * (vm_offset_t *) saddr = data; - saddr += sizeof(vm_offset_t); - complex = TRUE; - } - - if (is_port) { - mach_msg_type_name_t newname = - ipc_object_copyin_type(name); - ipc_object_t *objects = (ipc_object_t *) data; - mach_msg_type_number_t i; - - if (longform) - type->msgtl_name = newname; - else - ((mach_msg_type_t*)type)->msgt_name = newname; - - for (i = 0; i < number; i++) { - mach_port_t port = (mach_port_t) objects[i]; - ipc_object_t object; - - if (!MACH_PORT_VALID(port)) - continue; - - kr = ipc_object_copyin_compat(space, port, - name, dealloc, &object); - if (kr != KERN_SUCCESS) { - ipc_kmsg_clean_partial(kmsg, taddr, - TRUE, i); - return MACH_SEND_INVALID_RIGHT; - } - - if ((newname == MACH_MSG_TYPE_PORT_RECEIVE) && - ipc_port_check_circularity( - (ipc_port_t) object, - (ipc_port_t) dest)) - kmsg->ikm_header.msgh_bits |= - MACH_MSGH_BITS_CIRCULAR; - - objects[i] = object; - } - - complex = TRUE; - } - } - - if (complex) - kmsg->ikm_header.msgh_bits |= MACH_MSGH_BITS_COMPLEX; - - return MACH_MSG_SUCCESS; -} - -/* - * Routine: ipc_kmsg_copyout_compat - * Purpose: - * "Copy-out" port rights and out-of-line memory - * in the message, producing an old IPC message. - * - * Doesn't bother to handle the header atomically. - * Skips over errors. Problem ports produce MACH_PORT_NULL - * (MACH_PORT_DEAD is never produced), and problem memory - * produces a zero address. - * Conditions: - * Nothing locked. - * Returns: - * MACH_MSG_SUCCESS Copied out rights and memory. - */ - -mach_msg_return_t -ipc_kmsg_copyout_compat(kmsg, space, map) - ipc_kmsg_t kmsg; - ipc_space_t space; - vm_map_t map; -{ - msg_header_t msg; - mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits; - ipc_object_t dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port; - ipc_object_t reply = (ipc_object_t) kmsg->ikm_header.msgh_local_port; - mach_port_t dest_name, reply_name; - vm_offset_t saddr, eaddr; - kern_return_t kr; - - assert(IO_VALID(dest)); - - io_lock(dest); - if (io_active(dest)) { - mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits); - - ipc_object_copyout_dest(space, dest, dest_type, &dest_name); - /* dest is unlocked */ - } else { - io_release(dest); - io_check_unlock(dest); - dest_name = MACH_PORT_NULL; - } - - if (IO_VALID(reply)) { - mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits); - - kr = ipc_object_copyout_compat(space, reply, reply_type, - &reply_name); - if (kr != KERN_SUCCESS) { - ipc_object_destroy(reply, reply_type); - reply_name = MACH_PORT_NULL; - } - } else - reply_name = MACH_PORT_NULL; - - msg.msg_unused = 0; - msg.msg_simple = (mbits & MACH_MSGH_BITS_COMPLEX) ? FALSE : TRUE; - msg.msg_size = (msg_size_t) kmsg->ikm_header.msgh_size; - msg.msg_type = (integer_t) kmsg->ikm_header.msgh_seqno; - msg.msg_local_port = (port_name_t) dest_name; - msg.msg_remote_port = (port_name_t) reply_name; - msg.msg_id = (integer_t) kmsg->ikm_header.msgh_id; - * (msg_header_t *) &kmsg->ikm_header = msg; - - if (msg.msg_simple) - return MACH_MSG_SUCCESS; - - saddr = (vm_offset_t) (&kmsg->ikm_header + 1); - eaddr = (vm_offset_t) &kmsg->ikm_header + kmsg->ikm_header.msgh_size; - - while (saddr < eaddr) { - vm_offset_t taddr = saddr; - mach_msg_type_long_t *type; - mach_msg_type_name_t name; - mach_msg_type_size_t size; - mach_msg_type_number_t number; - boolean_t is_inline, longform, is_port; - vm_size_t length; - vm_offset_t addr; - - type = (mach_msg_type_long_t *) saddr; - is_inline = ((mach_msg_type_t*)type)->msgt_inline; - longform = ((mach_msg_type_t*)type)->msgt_longform; - if (longform) { - /* This must be aligned */ - if ((sizeof(natural_t) > sizeof(mach_msg_type_t)) && - (is_misaligned(type))) { - saddr = ptr_align(saddr); - continue; - } - name = type->msgtl_name; - size = type->msgtl_size; - number = type->msgtl_number; - saddr += sizeof(mach_msg_type_long_t); - } else { - name = ((mach_msg_type_t*)type)->msgt_name; - size = ((mach_msg_type_t*)type)->msgt_size; - number = ((mach_msg_type_t*)type)->msgt_number; - saddr += sizeof(mach_msg_type_t); - } - - /* padding (ptrs and ports) ? */ - if ((sizeof(natural_t) > sizeof(mach_msg_type_t)) && - ((size >> 3) == sizeof(natural_t))) - saddr = ptr_align(saddr); - - /* calculate length of data in bytes, rounding up */ - - length = ((number * size) + 7) >> 3; - - is_port = MACH_MSG_TYPE_PORT_ANY(name); - - if (is_port) { - mach_port_t *objects; - mach_msg_type_number_t i; - mach_msg_type_name_t newname; - - if (!is_inline && (length != 0)) { - /* first allocate memory in the map */ - - kr = vm_allocate(map, &addr, length, TRUE); - if (kr != KERN_SUCCESS) { - ipc_kmsg_clean_body(taddr, saddr); - goto vm_copyout_failure; - } - } - - newname = ipc_object_copyout_type_compat(name); - if (longform) - type->msgtl_name = newname; - else - ((mach_msg_type_t*)type)->msgt_name = newname; - - objects = (mach_port_t *) - (is_inline ? saddr : * (vm_offset_t *) saddr); - - /* copyout port rights carried in the message */ - - for (i = 0; i < number; i++) { - ipc_object_t object = - (ipc_object_t) objects[i]; - - if (!IO_VALID(object)) { - objects[i] = MACH_PORT_NULL; - continue; - } - - kr = ipc_object_copyout_compat(space, object, - name, &objects[i]); - if (kr != KERN_SUCCESS) { - ipc_object_destroy(object, name); - objects[i] = MACH_PORT_NULL; - } - } - } - - if (is_inline) { - /* inline data sizes round up to int boundaries */ - - saddr += (length + 3) &~ 3; - } else { - vm_offset_t data = * (vm_offset_t *) saddr; - - /* copyout memory carried in the message */ - - if (length == 0) { - assert(data == 0); - addr = 0; - } else if (is_port) { - /* copyout to memory allocated above */ - - (void) copyoutmap(map, (char *) data, - (char *) addr, length); - kfree(data, length); - } else { - vm_map_copy_t copy = (vm_map_copy_t) data; - - kr = vm_map_copyout(map, &addr, copy); - if (kr != KERN_SUCCESS) { - vm_map_copy_discard(copy); - - vm_copyout_failure: - - addr = 0; - } - } - - * (vm_offset_t *) saddr = addr; - saddr += sizeof(vm_offset_t); - } - } - - return MACH_MSG_SUCCESS; -} - -#endif /* MACH_IPC_COMPAT */ - #if MACH_KDB char * diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h index 32cf828..7617692 100644 --- a/ipc/ipc_kmsg.h +++ b/ipc/ipc_kmsg.h @@ -266,13 +266,4 @@ ipc_kmsg_copyout_pseudo(/* ipc_kmsg_t, ipc_space_t, vm_map_t */); extern void ipc_kmsg_copyout_dest(/* ipc_kmsg_t, ipc_space_t */); -#if MACH_IPC_COMPAT - -extern mach_msg_return_t -ipc_kmsg_copyin_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */); - -extern mach_msg_return_t -ipc_kmsg_copyout_compat(/* ipc_kmsg_t, ipc_space_t, vm_map_t */); - -#endif /* MACH_IPC_COMPAT */ #endif /* _IPC_IPC_KMSG_H_ */ diff --git a/ipc/ipc_marequest.c b/ipc/ipc_marequest.c index 5826baf..e62001e 100644 --- a/ipc/ipc_marequest.c +++ b/ipc/ipc_marequest.c @@ -157,9 +157,6 @@ ipc_marequest_init() * * The "notify" argument should name a receive right * that is used to create the send-once notify port. - * - * [MACH_IPC_COMPAT] If "notify" is MACH_PORT_NULL, - * then an old-style msg-accepted request is created. * Conditions: * Nothing locked; refs held for space and port. * Returns: @@ -184,10 +181,6 @@ ipc_marequest_create(space, port, notify, marequestp) ipc_marequest_t marequest; ipc_marequest_bucket_t bucket; -#if !MACH_IPC_COMPAT - assert(notify != MACH_PORT_NULL); -#endif /* !MACH_IPC_COMPAT */ - marequest = imar_alloc(); if (marequest == IMAR_NULL) return MACH_SEND_NO_NOTIFY; @@ -222,11 +215,6 @@ ipc_marequest_create(space, port, notify, marequestp) return MACH_SEND_NOTIFY_IN_PROGRESS; } -#if MACH_IPC_COMPAT - if (notify == MACH_PORT_NULL) - soright = IP_NULL; - else -#endif /* MACH_IPC_COMPAT */ if ((soright = ipc_port_lookup_notify(space, notify)) == IP_NULL) { is_write_unlock(space); @@ -249,11 +237,6 @@ ipc_marequest_create(space, port, notify, marequestp) imarb_unlock(bucket); } else { -#if MACH_IPC_COMPAT - if (notify == MACH_PORT_NULL) - soright = IP_NULL; - else -#endif /* MACH_IPC_COMPAT */ if ((soright = ipc_port_lookup_notify(space, notify)) == IP_NULL) { is_write_unlock(space); @@ -368,9 +351,6 @@ ipc_marequest_destroy(marequest) ipc_space_t space = marequest->imar_space; mach_port_t name; ipc_port_t soright; -#if MACH_IPC_COMPAT - ipc_port_t sright = IP_NULL; -#endif /* MACH_IPC_COMPAT */ is_write_lock(space); @@ -405,10 +385,6 @@ ipc_marequest_destroy(marequest) entry->ie_bits &= ~IE_BITS_MAREQUEST; -#if MACH_IPC_COMPAT - if (soright == IP_NULL) - sright = ipc_space_make_notify(space); -#endif /* MACH_IPC_COMPAT */ } else name = MACH_PORT_NULL; } @@ -418,18 +394,6 @@ ipc_marequest_destroy(marequest) imar_free(marequest); -#if MACH_IPC_COMPAT - if (soright == IP_NULL) { - if (IP_VALID(sright)) { - assert(name != MACH_PORT_NULL); - ipc_notify_msg_accepted_compat(sright, name); - } - - return; - } - assert(sright == IP_NULL); -#endif /* MACH_IPC_COMPAT */ - assert(soright != IP_NULL); ipc_notify_msg_accepted(soright, name); } diff --git a/ipc/ipc_notify.c b/ipc/ipc_notify.c index 3dea9fc..6a3d381 100644 --- a/ipc/ipc_notify.c +++ b/ipc/ipc_notify.c @@ -50,19 +50,7 @@ mach_no_senders_notification_t ipc_notify_no_senders_template; mach_send_once_notification_t ipc_notify_send_once_template; mach_dead_name_notification_t ipc_notify_dead_name_template; -#if MACH_IPC_COMPAT -/* - * When notification messages are received via the old - * msg_receive trap, the msg_type field should contain - * MSG_TYPE_EMERGENCY. We arrange for this by putting - * MSG_TYPE_EMERGENCY into msgh_seqno, which - * ipc_kmsg_copyout_compat copies to msg_type. - */ - -#define NOTIFY_MSGH_SEQNO MSG_TYPE_EMERGENCY -#else /* MACH_IPC_COMPAT */ #define NOTIFY_MSGH_SEQNO 0 -#endif /* MACH_IPC_COMPAT */ /* * Routine: ipc_notify_init_port_deleted @@ -463,123 +451,3 @@ ipc_notify_dead_name(port, name) ipc_mqueue_send_always(kmsg); } - -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_notify_port_deleted_compat - * Purpose: - * Send a port-deleted notification. - * Sends it to a send right instead of a send-once right. - * Conditions: - * Nothing locked. - * Consumes a ref/sright for port. - */ - -void -ipc_notify_port_deleted_compat(port, name) - ipc_port_t port; - mach_port_t name; -{ - ipc_kmsg_t kmsg; - mach_port_deleted_notification_t *n; - - kmsg = ikm_alloc(sizeof *n); - if (kmsg == IKM_NULL) { - printf("dropped port-deleted-compat (0x%08x, 0x%x)\n", - port, name); - ipc_port_release_send(port); - return; - } - - ikm_init(kmsg, sizeof *n); - n = (mach_port_deleted_notification_t *) &kmsg->ikm_header; - *n = ipc_notify_port_deleted_template; - - n->not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); - n->not_header.msgh_remote_port = (mach_port_t) port; - n->not_port = name; - - ipc_mqueue_send_always(kmsg); -} - -/* - * Routine: ipc_notify_msg_accepted_compat - * Purpose: - * Send a msg-accepted notification. - * Sends it to a send right instead of a send-once right. - * Conditions: - * Nothing locked. - * Consumes a ref/sright for port. - */ - -void -ipc_notify_msg_accepted_compat(port, name) - ipc_port_t port; - mach_port_t name; -{ - ipc_kmsg_t kmsg; - mach_msg_accepted_notification_t *n; - - kmsg = ikm_alloc(sizeof *n); - if (kmsg == IKM_NULL) { - printf("dropped msg-accepted-compat (0x%08x, 0x%x)\n", - port, name); - ipc_port_release_send(port); - return; - } - - ikm_init(kmsg, sizeof *n); - n = (mach_msg_accepted_notification_t *) &kmsg->ikm_header; - *n = ipc_notify_msg_accepted_template; - - n->not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); - n->not_header.msgh_remote_port = (mach_port_t) port; - n->not_port = name; - - ipc_mqueue_send_always(kmsg); -} - -/* - * Routine: ipc_notify_port_destroyed_compat - * Purpose: - * Send a port-destroyed notification. - * Sends it to a send right instead of a send-once right. - * Conditions: - * Nothing locked. - * Consumes a ref/sright for port. - * Consumes a ref for right, which should be a receive right - * prepped for placement into a message. (In-transit, - * or in-limbo if a circularity was detected.) - */ - -void -ipc_notify_port_destroyed_compat(port, right) - ipc_port_t port; - ipc_port_t right; -{ - ipc_kmsg_t kmsg; - mach_port_destroyed_notification_t *n; - - kmsg = ikm_alloc(sizeof *n); - if (kmsg == IKM_NULL) { - printf("dropped port-destroyed-compat (0x%08x, 0x%08x)\n", - port, right); - ipc_port_release_send(port); - ipc_port_release_receive(right); - return; - } - - ikm_init(kmsg, sizeof *n); - n = (mach_port_destroyed_notification_t *) &kmsg->ikm_header; - *n = ipc_notify_port_destroyed_template; - - n->not_header.msgh_bits = MACH_MSGH_BITS_COMPLEX | - MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); - n->not_header.msgh_remote_port = (mach_port_t) port; - n->not_port = (mach_port_t) right; - - ipc_mqueue_send_always(kmsg); -} - -#endif /* MACH_IPC_COMPAT */ diff --git a/ipc/ipc_notify.h b/ipc/ipc_notify.h index 433d919..60872a9 100644 --- a/ipc/ipc_notify.h +++ b/ipc/ipc_notify.h @@ -55,16 +55,4 @@ ipc_notify_send_once(/* ipc_port_t */); extern void ipc_notify_dead_name(/* ipc_port_t, mach_port_t */); -#if MACH_IPC_COMPAT - -extern void -ipc_notify_port_deleted_compat(/* ipc_port_t, mach_port_t */); - -extern void -ipc_notify_msg_accepted_compat(/* ipc_port_t, mach_port_t */); - -extern void -ipc_notify_port_destroyed_compat(/* ipc_port_t, ipc_port_t */); - -#endif /* MACH_IPC_COMPAT */ #endif /* _IPC_IPC_NOTIFY_H_ */ diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c index 74d21f9..a7a7ddb 100644 --- a/ipc/ipc_object.c +++ b/ipc/ipc_object.c @@ -368,14 +368,6 @@ ipc_object_copyin_type( case MACH_MSG_TYPE_COPY_SEND: return MACH_MSG_TYPE_PORT_SEND; -#if MACH_IPC_COMPAT - case MSG_TYPE_PORT: - return MACH_MSG_TYPE_PORT_SEND; - - case MSG_TYPE_PORT_ALL: - return MACH_MSG_TYPE_PORT_RECEIVE; -#endif /* MACH_IPC_COMPAT */ - default: #if MACH_ASSERT assert(!"ipc_object_copyin_type: strange rights"); @@ -966,323 +958,6 @@ ipc_object_rename( return kr; } -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_object_copyout_type_compat - * Purpose: - * Convert a carried type name to an old type name. - */ - -mach_msg_type_name_t -ipc_object_copyout_type_compat(msgt_name) - mach_msg_type_name_t msgt_name; -{ - switch (msgt_name) { - case MACH_MSG_TYPE_PORT_SEND: - case MACH_MSG_TYPE_PORT_SEND_ONCE: - return MSG_TYPE_PORT; - - case MACH_MSG_TYPE_PORT_RECEIVE: - return MSG_TYPE_PORT_ALL; - - default: -#if MACH_ASSERT - assert(!"ipc_object_copyout_type_compat: strange rights"); -#else - panic("ipc_object_copyout_type_compat: strange rights"); -#endif - } -} - -/* - * Routine: ipc_object_copyin_compat - * Purpose: - * Copyin a capability from a space. - * If successful, the caller gets a ref - * for the resulting object, which is always valid. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Acquired a valid object. - * KERN_INVALID_TASK The space is dead. - * KERN_INVALID_NAME Name doesn't exist in space. - * KERN_INVALID_RIGHT Name doesn't denote correct right. - */ - -kern_return_t -ipc_object_copyin_compat(space, name, msgt_name, dealloc, objectp) - ipc_space_t space; - mach_port_t name; - mach_msg_type_name_t msgt_name; - boolean_t dealloc; - ipc_object_t *objectp; -{ - ipc_entry_t entry; - kern_return_t kr; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return kr; - /* space is write-locked and active */ - - kr = ipc_right_copyin_compat(space, name, entry, - msgt_name, dealloc, objectp); - /* space is unlocked */ - return kr; -} - -/* - * Routine: ipc_object_copyin_header - * Purpose: - * Copyin a capability from a space. - * If successful, the caller gets a ref - * for the resulting object, which is always valid. - * The type of the acquired capability is returned. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Acquired a valid object. - * KERN_INVALID_TASK The space is dead. - * KERN_INVALID_NAME Name doesn't exist in space. - * KERN_INVALID_RIGHT Name doesn't denote correct right. - */ - -kern_return_t -ipc_object_copyin_header(space, name, objectp, msgt_namep) - ipc_space_t space; - mach_port_t name; - ipc_object_t *objectp; - mach_msg_type_name_t *msgt_namep; -{ - ipc_entry_t entry; - kern_return_t kr; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return kr; - /* space is write-locked and active */ - - kr = ipc_right_copyin_header(space, name, entry, - objectp, msgt_namep); - /* space is unlocked */ - return kr; -} - -/* - * Routine: ipc_object_copyout_compat - * Purpose: - * Copyout a capability, placing it into a space. - * If successful, consumes a ref for the object. - * - * Marks new entries with IE_BITS_COMPAT. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Copied out object, consumed ref. - * KERN_INVALID_TASK The space is dead. - * KERN_INVALID_CAPABILITY The object is dead. - * KERN_NO_SPACE No room in space for another right. - * KERN_RESOURCE_SHORTAGE No memory available. - */ - -kern_return_t -ipc_object_copyout_compat(space, object, msgt_name, namep) - ipc_space_t space; - ipc_object_t object; - mach_msg_type_name_t msgt_name; - mach_port_t *namep; -{ - mach_port_t name; - ipc_entry_t entry; - ipc_port_t port; - kern_return_t kr; - - assert(IO_VALID(object)); - assert(io_otype(object) == IOT_PORT); - port = (ipc_port_t) object; - - is_write_lock(space); - - for (;;) { - ipc_port_request_index_t request; - - if (!space->is_active) { - is_write_unlock(space); - return KERN_INVALID_TASK; - } - - if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && - ipc_right_reverse(space, (ipc_object_t) port, - &name, &entry)) { - /* port is locked and active */ - - assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE); - break; - } - - kr = ipc_entry_get(space, &name, &entry); - if (kr != KERN_SUCCESS) { - /* unlocks/locks space, so must start again */ - - kr = ipc_entry_grow_table(space); - if (kr != KERN_SUCCESS) - return kr; /* space is unlocked */ - - continue; - } - - assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); - assert(entry->ie_object == IO_NULL); - - ip_lock(port); - if (!ip_active(port)) { - ip_unlock(port); - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - return KERN_INVALID_CAPABILITY; - } - - kr = ipc_port_dnrequest(port, name, ipr_spacem(space), - &request); - if (kr != KERN_SUCCESS) { - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - - kr = ipc_port_dngrow(port); - /* port is unlocked */ - if (kr != KERN_SUCCESS) - return kr; - - is_write_lock(space); - continue; - } - - is_reference(space); /* for dnrequest */ - entry->ie_object = (ipc_object_t) port; - entry->ie_request = request; - entry->ie_bits |= IE_BITS_COMPAT; - break; - } - - /* space is write-locked and active, port is locked and active */ - - kr = ipc_right_copyout(space, name, entry, - msgt_name, TRUE, (ipc_object_t) port); - /* object is unlocked */ - is_write_unlock(space); - - if (kr == KERN_SUCCESS) - *namep = name; - return kr; -} - -/* - * Routine: ipc_object_copyout_name_compat - * Purpose: - * Copyout a capability, placing it into a space. - * The specified name is used for the capability. - * If successful, consumes a ref for the object. - * - * Like ipc_object_copyout_name, except that - * the name can't be in use at all, even for the same - * port, and IE_BITS_COMPAT gets turned on. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Copied out object, consumed ref. - * KERN_INVALID_TASK The space is dead. - * KERN_INVALID_CAPABILITY The object is dead. - * KERN_RESOURCE_SHORTAGE No memory available. - * KERN_RIGHT_EXISTS Space has rights under another name. - * KERN_NAME_EXISTS Name is already used. - */ - -kern_return_t -ipc_object_copyout_name_compat(space, object, msgt_name, name) - ipc_space_t space; - ipc_object_t object; - mach_msg_type_name_t msgt_name; - mach_port_t name; -{ - ipc_entry_t entry; - ipc_port_t port; - kern_return_t kr; - - assert(IO_VALID(object)); - assert(io_otype(object) == IOT_PORT); - port = (ipc_port_t) object; - - for (;;) { - mach_port_t oname; - ipc_entry_t oentry; - ipc_port_request_index_t request; - - kr = ipc_entry_alloc_name(space, name, &entry); - if (kr != KERN_SUCCESS) - return kr; - /* space is write-locked and active */ - - if (ipc_right_inuse(space, name, entry)) - return KERN_NAME_EXISTS; /* space is unlocked */ - - assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); - assert(entry->ie_object == IO_NULL); - - if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && - ipc_right_reverse(space, (ipc_object_t) port, - &oname, &oentry)) { - /* port is locked and active */ - - ip_unlock(port); - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - return KERN_RIGHT_EXISTS; - } - - ip_lock(port); - if (!ip_active(port)) { - ip_unlock(port); - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - return KERN_INVALID_CAPABILITY; - } - - kr = ipc_port_dnrequest(port, name, ipr_spacem(space), - &request); - if (kr != KERN_SUCCESS) { - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - - kr = ipc_port_dngrow(port); - /* port is unlocked */ - if (kr != KERN_SUCCESS) - return kr; - - continue; - } - - is_reference(space); /* for dnrequest */ - entry->ie_object = (ipc_object_t) port; - entry->ie_request = request; - entry->ie_bits |= IE_BITS_COMPAT; - break; - } - - /* space is write-locked and active, port is locked and active */ - - kr = ipc_right_copyout(space, name, entry, - msgt_name, TRUE, (ipc_object_t) port); - /* object is unlocked */ - is_write_unlock(space); - - assert(kr == KERN_SUCCESS); - return kr; -} - -#endif /* MACH_IPC_COMPAT */ - - #if MACH_KDB #define printf kdbprintf diff --git a/ipc/ipc_object.h b/ipc/ipc_object.h index 0a0184a..7c6eb4e 100644 --- a/ipc/ipc_object.h +++ b/ipc/ipc_object.h @@ -160,30 +160,6 @@ ipc_object_copyout_dest(/* ipc_space_t, ipc_object_t, extern kern_return_t ipc_object_rename(/* ipc_space_t, mach_port_t, mach_port_t */); -#if MACH_IPC_COMPAT - -extern mach_msg_type_name_t -ipc_object_copyout_type_compat(/* mach_msg_type_name_t */); - -extern kern_return_t -ipc_object_copyin_compat(/* ipc_space_t, mach_port_t, - mach_msg_type_name_t, boolean_t, - ipc_object_t * */); - -extern kern_return_t -ipc_object_copyin_header(/* ipc_space_t, mach_port_t, - ipc_object_t *, mach_msg_type_name_t * */); - -extern kern_return_t -ipc_object_copyout_compat(/* ipc_space_t, ipc_object_t, - mach_msg_type_name_t, mach_port_t * */); - -extern kern_return_t -ipc_object_copyout_name_compat(/* ipc_space_t, ipc_object_t, - mach_msg_type_name_t, mach_port_t */); - -#endif /* MACH_IPC_COMPAT */ - extern void ipc_object_print(/* ipc_object_t */); diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c index f19cca6..ce0dbeb 100644 --- a/ipc/ipc_port.c +++ b/ipc/ipc_port.c @@ -570,55 +570,6 @@ ipc_port_alloc_name( return KERN_SUCCESS; } -#if MACH_IPC_COMPAT -/* - * Routine: ipc_port_delete_compat - * Purpose: - * Find and destroy a compat entry for a dead port. - * If successful, generate a port-deleted notification. - * Conditions: - * Nothing locked; the port is dead. - * Frees a ref for the space. - */ - -void -ipc_port_delete_compat(port, space, name) - ipc_port_t port; - ipc_space_t space; - mach_port_t name; -{ - ipc_entry_t entry; - kern_return_t kr; - - assert(!ip_active(port)); - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr == KERN_SUCCESS) { - ipc_port_t sright; - - /* space is write-locked and active */ - - if ((ipc_port_t) entry->ie_object == port) { - assert(entry->ie_bits & IE_BITS_COMPAT); - - sright = ipc_space_make_notify(space); - - kr = ipc_right_destroy(space, name, entry); - /* space is unlocked */ - assert(kr == KERN_INVALID_NAME); - } else { - is_write_unlock(space); - sright = IP_NULL; - } - - if (IP_VALID(sright)) - ipc_notify_port_deleted_compat(sright, name); - } - - is_release(space); -} -#endif /* MACH_IPC_COMPAT */ - /* * Routine: ipc_port_destroy * Purpose: @@ -662,28 +613,6 @@ ipc_port_destroy( port->ip_destination = IP_NULL; ip_unlock(port); -#if MACH_IPC_COMPAT - /* - * pdrequest might actually be a send right instead - * of a send-once right, indicated by the low bit - * of the pointer value. If this is the case, - * we must use ipc_notify_port_destroyed_compat. - */ - - if (ip_pdsendp(pdrequest)) { - ipc_port_t sright = ip_pdsend(pdrequest); - - if (!ipc_port_check_circularity(port, sright)) { - /* consumes our refs for port and sright */ - ipc_notify_port_destroyed_compat(sright, port); - return; - } else { - /* consume sright and destroy port */ - ipc_port_release_send(sright); - } - } else -#endif /* MACH_IPC_COMPAT */ - if (!ipc_port_check_circularity(port, pdrequest)) { /* consumes our refs for port and pdrequest */ ipc_notify_port_destroyed(pdrequest, port); @@ -771,14 +700,6 @@ ipc_port_destroy( soright = ipr->ipr_soright; assert(soright != IP_NULL); -#if MACH_IPC_COMPAT - if (ipr_spacep(soright)) { - ipc_port_delete_compat(port, - ipr_space(soright), name); - continue; - } -#endif /* MACH_IPC_COMPAT */ - ipc_notify_dead_name(soright, name); } @@ -1276,166 +1197,6 @@ ipc_port_dealloc_special( ipc_port_destroy(port); } -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_port_alloc_compat - * Purpose: - * Allocate a port. - * Conditions: - * Nothing locked. If successful, the port is returned - * locked. (The caller doesn't have a reference.) - * - * Like ipc_port_alloc, except that the new entry - * is IE_BITS_COMPAT. - * Returns: - * KERN_SUCCESS The port is allocated. - * KERN_INVALID_TASK The space is dead. - * KERN_NO_SPACE No room for an entry in the space. - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -ipc_port_alloc_compat(space, namep, portp) - ipc_space_t space; - mach_port_t *namep; - ipc_port_t *portp; -{ - ipc_port_t port; - ipc_entry_t entry; - mach_port_t name; - ipc_table_size_t its; - ipc_port_request_t table; - ipc_table_elems_t size; - ipc_port_request_index_t free, i; - kern_return_t kr; - - port = ip_alloc(); - if (port == IP_NULL) - return KERN_RESOURCE_SHORTAGE; - - its = &ipc_table_dnrequests[0]; - table = it_dnrequests_alloc(its); - if (table == IPR_NULL) { - ip_free(port); - return KERN_RESOURCE_SHORTAGE; - } - - kr = ipc_entry_alloc(space, &name, &entry); - if (kr != KERN_SUCCESS) { - ip_free(port); - it_dnrequests_free(its, table); - return kr; - } - /* space is write-locked */ - - entry->ie_object = (ipc_object_t) port; - entry->ie_request = 1; - entry->ie_bits |= IE_BITS_COMPAT|MACH_PORT_TYPE_RECEIVE; - - ip_lock_init(port); - ip_lock(port); - is_write_unlock(space); - - port->ip_references = 1; /* for entry, not caller */ - port->ip_bits = io_makebits(TRUE, IOT_PORT, 0); - - ipc_port_init(port, space, name); - - size = its->its_size; - assert(size > 1); - free = 0; - - for (i = 2; i < size; i++) { - ipc_port_request_t ipr = &table[i]; - - ipr->ipr_name = MACH_PORT_NULL; - ipr->ipr_next = free; - free = i; - } - - table->ipr_next = free; - table->ipr_size = its; - port->ip_dnrequests = table; - - table[1].ipr_name = name; - table[1].ipr_soright = ipr_spacem(space); - is_reference(space); - - *namep = name; - *portp = port; - return KERN_SUCCESS; -} - -/* - * Routine: ipc_port_copyout_send_compat - * Purpose: - * Copyout a naked send right (possibly null/dead), - * or if that fails, destroy the right. - * Like ipc_port_copyout_send, except that if a - * new translation is created it has the compat bit. - * Conditions: - * Nothing locked. - */ - -mach_port_t -ipc_port_copyout_send_compat(sright, space) - ipc_port_t sright; - ipc_space_t space; -{ - mach_port_t name; - - if (IP_VALID(sright)) { - kern_return_t kr; - - kr = ipc_object_copyout_compat(space, (ipc_object_t) sright, - MACH_MSG_TYPE_PORT_SEND, &name); - if (kr != KERN_SUCCESS) { - ipc_port_release_send(sright); - name = MACH_PORT_NULL; - } - } else - name = (mach_port_t) sright; - - return name; -} - -/* - * Routine: ipc_port_copyout_receiver - * Purpose: - * Copyout a port reference (possibly null) - * by giving the caller his name for the port, - * if he is the receiver. - * Conditions: - * Nothing locked. Consumes a ref for the port. - */ - -mach_port_t -ipc_port_copyout_receiver(port, space) - ipc_port_t port; - ipc_space_t space; -{ - mach_port_t name; - - if (!IP_VALID(port)) - return MACH_PORT_NULL; - - ip_lock(port); - if (port->ip_receiver == space) { - name = port->ip_receiver_name; - assert(MACH_PORT_VALID(name)); - } else - name = MACH_PORT_NULL; - - ip_release(port); - ip_check_unlock(port); - - return name; -} - -#endif /* MACH_IPC_COMPAT */ - - #if MACH_KDB #define printf kdbprintf diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h index 4b269b6..3424f88 100644 --- a/ipc/ipc_port.h +++ b/ipc/ipc_port.h @@ -148,30 +148,6 @@ typedef struct ipc_port_request { #define IPR_NULL ((ipc_port_request_t) 0) -#if MACH_IPC_COMPAT -/* - * For backwards compatibility, the ip_pdrequest field can hold a - * send right instead of a send-once right. This is indicated by - * the low bit of the pointer. This works because the zone package - * guarantees that the two low bits of port pointers are zero. - */ - -#define ip_pdsendp(soright) ((unsigned int)(soright) & 1) -#define ip_pdsend(soright) ((ipc_port_t)((unsigned int)(soright) &~ 1)) -#define ip_pdsendm(sright) ((ipc_port_t)((unsigned int)(sright) | 1)) - -/* - * For backwards compatibility, the ipr_soright field can hold - * a space pointer. This is indicated by the low bit of the pointer. - * This works because the zone package guarantees that the two low - * bits of port and space pointers are zero. - */ - -#define ipr_spacep(soright) ((unsigned int)(soright) & 1) -#define ipr_space(soright) ((ipc_space_t)((unsigned int)(soright) &~ 1)) -#define ipr_spacem(space) ((ipc_port_t)((unsigned int)(space) | 1)) -#endif /* MACH_IPC_COMPAT */ - /* * Taking the ipc_port_multiple lock grants the privilege * to lock multiple ports at once. No ports must locked @@ -349,19 +325,6 @@ ipc_port_dealloc_special(/* ipc_port_t */); #define ipc_port_release(port) \ ipc_object_release(&(port)->ip_object) -#if MACH_IPC_COMPAT - -extern kern_return_t -ipc_port_alloc_compat(/* ipc_space_t, mach_port_t *, ipc_port_t * */); - -extern mach_port_t -ipc_port_copyout_send_compat(/* ipc_port_t, ipc_space_t */); - -extern mach_port_t -ipc_port_copyout_receiver(/* ipc_port_t, ipc_space_t */); - -#endif /* MACH_IPC_COMPAT */ - extern void ipc_port_print(/* ipc_port_t */); diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c index 7e7a5f2..41fe3de 100644 --- a/ipc/ipc_right.c +++ b/ipc/ipc_right.c @@ -214,13 +214,6 @@ ipc_right_dnrequest( /* port is locked and active */ if (notify == IP_NULL) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - assert(entry->ie_request != 0); - - previous = IP_NULL; - } else -#endif /* MACH_IPC_COMPAT */ previous = ipc_right_dncancel_macro( space, port, name, entry); @@ -260,20 +253,10 @@ ipc_right_dnrequest( ip_unlock(port); entry->ie_request = request; -#if MACH_IPC_COMPAT - entry->ie_bits = bits &~ IE_BITS_COMPAT; -#endif /* MACH_IPC_COMPAT */ is_write_unlock(space); break; } -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - is_write_unlock(space); - return KERN_INVALID_NAME; - } -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; assert(bits & MACH_PORT_TYPE_DEAD_NAME); } @@ -334,19 +317,6 @@ ipc_right_dncancel( dnrequest = ipc_port_dncancel(port, name, entry->ie_request); entry->ie_request = 0; -#if MACH_IPC_COMPAT - assert(!ipr_spacep(dnrequest) == !(entry->ie_bits & IE_BITS_COMPAT)); - - /* if this is actually a space ptr, just release the ref */ - - if (entry->ie_bits & IE_BITS_COMPAT) { - assert(space == ipr_space(dnrequest)); - - is_release(space); - dnrequest = IP_NULL; - } -#endif /* MACH_IPC_COMPAT */ - return dnrequest; } @@ -369,57 +339,6 @@ ipc_right_inuse(space, name, entry) ipc_entry_bits_t bits = entry->ie_bits; if (IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE) { -#if MACH_IPC_COMPAT - mach_port_type_t type = IE_BITS_TYPE(bits); - - /* - * There is yet hope. If the port has died, we - * must clean up the entry so it's as good as new. - */ - - if ((bits & IE_BITS_COMPAT) && - ((type == MACH_PORT_TYPE_SEND) || - (type == MACH_PORT_TYPE_SEND_ONCE))) { - ipc_port_t port; - boolean_t active; - - assert(IE_BITS_UREFS(bits) > 0); - assert(entry->ie_request != 0); - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - active = ip_active(port); - ip_unlock(port); - - if (!active) { - if (type == MACH_PORT_TYPE_SEND) { - /* clean up msg-accepted request */ - - if (bits & IE_BITS_MAREQUEST) - ipc_marequest_cancel( - space, name); - - ipc_hash_delete( - space, (ipc_object_t) port, - name, entry); - } else { - assert(IE_BITS_UREFS(bits) == 1); - assert(!(bits & IE_BITS_MAREQUEST)); - } - - ipc_port_release(port); - - entry->ie_request = 0; - entry->ie_object = IO_NULL; - entry->ie_bits &= ~IE_BITS_RIGHT_MASK; - - return FALSE; - } - } -#endif /* MACH_IPC_COMPAT */ - is_write_unlock(space); return TRUE; } @@ -437,11 +356,6 @@ ipc_right_inuse(space, name, entry) * If returns FALSE, the port is also locked and active. * Otherwise, entry is converted to a dead name, freeing * a reference to port. - * - * [MACH_IPC_COMPAT] If the port is dead, and this is a - * compat mode entry, then the port reference is released - * and the entry is destroyed. The call returns TRUE, - * and the space is left locked. */ boolean_t @@ -487,18 +401,6 @@ ipc_right_check(space, port, name, entry) ipc_port_release(port); -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - assert(entry->ie_request != 0); - entry->ie_request = 0; - - entry->ie_object = IO_NULL; - ipc_entry_dealloc(space, name, entry); - - return TRUE; - } -#endif /* MACH_IPC_COMPAT */ - /* convert entry to dead name */ bits = (bits &~ IE_BITS_TYPE_MASK) | MACH_PORT_TYPE_DEAD_NAME; @@ -723,10 +625,6 @@ ipc_right_destroy( ipc_entry_dealloc(space, name, entry); is_write_unlock(space); -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - return KERN_INVALID_NAME; -#endif /* MACH_IPC_COMPAT */ break; } @@ -796,8 +694,6 @@ ipc_right_destroy( * Returns: * KERN_SUCCESS A user ref was released. * KERN_INVALID_RIGHT Entry has wrong type. - * KERN_INVALID_NAME [MACH_IPC_COMPAT] - * Caller should pretend lookup of entry failed. */ kern_return_t @@ -839,11 +735,6 @@ ipc_right_dealloc(space, name, entry) assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_DEAD_NAME); goto dead_name; @@ -878,11 +769,6 @@ ipc_right_dealloc(space, name, entry) assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_DEAD_NAME); goto dead_name; @@ -970,12 +856,6 @@ ipc_right_dealloc(space, name, entry) } return KERN_SUCCESS; - -#if MACH_IPC_COMPAT - invalid_name: - is_write_unlock(space); - return KERN_INVALID_NAME; -#endif /* MACH_IPC_COMPAT */ } /* @@ -991,8 +871,6 @@ ipc_right_dealloc(space, name, entry) * KERN_INVALID_RIGHT Entry has wrong type. * KERN_INVALID_VALUE Bad delta for the right. * KERN_UREFS_OVERFLOW OK delta, except would overflow. - * KERN_INVALID_NAME [MACH_IPC_COMPAT] - * Caller should pretend lookup of entry failed. */ kern_return_t @@ -1075,17 +953,6 @@ ipc_right_delta(space, name, entry, right, delta) assert(port->ip_receiver_name == name); assert(port->ip_receiver == space); -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - assert(entry->ie_request != 0); - dnrequest = ipc_right_dncancel(space, port, - name, entry); - assert(dnrequest == IP_NULL); - - entry->ie_object = IO_NULL; - ipc_entry_dealloc(space, name, entry); - } else -#endif /* MACH_IPC_COMPAT */ if (bits & MACH_PORT_TYPE_SEND) { assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_RECEIVE); @@ -1148,11 +1015,6 @@ ipc_right_delta(space, name, entry, right, delta) assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - assert(!(entry->ie_bits & MACH_PORT_TYPE_SEND_ONCE)); goto invalid_right; } @@ -1194,11 +1056,6 @@ ipc_right_delta(space, name, entry, right, delta) goto invalid_right; } -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; } else if ((bits & MACH_PORT_TYPE_DEAD_NAME) == 0) goto invalid_right; @@ -1246,11 +1103,6 @@ ipc_right_delta(space, name, entry, right, delta) assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - assert((entry->ie_bits & MACH_PORT_TYPE_SEND) == 0); goto invalid_right; } @@ -1331,12 +1183,6 @@ ipc_right_delta(space, name, entry, right, delta) urefs_overflow: is_write_unlock(space); return KERN_UREFS_OVERFLOW; - -#if MACH_IPC_COMPAT - invalid_name: - is_write_unlock(space); - return KERN_INVALID_NAME; -#endif /* MACH_IPC_COMPAT */ } /* @@ -1366,13 +1212,6 @@ ipc_right_info( ipc_port_t port = (ipc_port_t) entry->ie_object; if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - is_write_unlock(space); - return KERN_INVALID_NAME; - } -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_DEAD_NAME); } else @@ -1382,11 +1221,6 @@ ipc_right_info( type = IE_BITS_TYPE(bits); request = entry->ie_request; -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - type |= MACH_PORT_TYPE_COMPAT; - else -#endif /* MACH_IPC_COMPAT */ if (request != 0) type |= MACH_PORT_TYPE_DNREQUEST; if (bits & IE_BITS_MAREQUEST) @@ -1445,11 +1279,6 @@ ipc_right_copyin_check( ip_unlock(port); if (!active) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - return FALSE; -#endif /* MACH_IPC_COMPAT */ - break; } @@ -1627,11 +1456,6 @@ ipc_right_copyin( assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; goto copy_dead; } @@ -1674,11 +1498,6 @@ ipc_right_copyin( assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; goto move_dead; } @@ -1750,11 +1569,6 @@ ipc_right_copyin( assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - bits = entry->ie_bits; goto move_dead; } @@ -1829,11 +1643,6 @@ ipc_right_copyin( invalid_right: return KERN_INVALID_RIGHT; - -#if MACH_IPC_COMPAT - invalid_name: - return KERN_INVALID_NAME; -#endif /* MACH_IPC_COMPAT */ } /* @@ -1959,11 +1768,6 @@ ipc_right_copyin_two( assert(port != IP_NULL); if (ipc_right_check(space, port, name, entry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - goto invalid_name; -#endif /* MACH_IPC_COMPAT */ - goto invalid_right; } /* port is locked and active */ @@ -2012,11 +1816,6 @@ ipc_right_copyin_two( invalid_right: return KERN_INVALID_RIGHT; - -#if MACH_IPC_COMPAT - invalid_name: - return KERN_INVALID_NAME; -#endif /* MACH_IPC_COMPAT */ } /* @@ -2251,14 +2050,6 @@ ipc_right_rename( assert(port != IP_NULL); if (ipc_right_check(space, port, oname, oentry)) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) { - ipc_entry_dealloc(space, nname, nentry); - is_write_unlock(space); - return KERN_INVALID_NAME; - } -#endif /* MACH_IPC_COMPAT */ - bits = oentry->ie_bits; assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_DEAD_NAME); assert(oentry->ie_request == 0); @@ -2350,412 +2141,3 @@ ipc_right_rename( return KERN_SUCCESS; } - -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_right_copyin_compat - * Purpose: - * Copyin a capability from a space. - * If successful, the caller gets a ref - * for the resulting object, which is always valid. - * Conditions: - * The space is write-locked, and is unlocked upon return. - * The space must be active. - * Returns: - * KERN_SUCCESS Acquired a valid object. - * KERN_INVALID_RIGHT Name doesn't denote correct right. - * KERN_INVALID_NAME [MACH_IPC_COMPAT] - * Caller should pretend lookup of entry failed. - */ - -kern_return_t -ipc_right_copyin_compat(space, name, entry, msgt_name, dealloc, objectp) - ipc_space_t space; - mach_port_t name; - ipc_entry_t entry; - mach_msg_type_name_t msgt_name; - boolean_t dealloc; - ipc_object_t *objectp; -{ - ipc_entry_bits_t bits = entry->ie_bits; - - assert(space->is_active); - - switch (msgt_name) { - case MSG_TYPE_PORT: - if (dealloc) { - ipc_port_t port; - ipc_port_t dnrequest; - - /* - * Pulls a send right out of the space, - * leaving the space with no rights. - * Not allowed to destroy the port, - * so the space can't have receive rights. - * Doesn't operate on dead names. - */ - - if (IE_BITS_TYPE(bits) != MACH_PORT_TYPE_SEND) - goto invalid_right; - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - if (ipc_right_check(space, port, name, entry)) { - if (bits & IE_BITS_COMPAT) - goto invalid_name; - - goto invalid_right; - } - /* port is locked and active */ - - dnrequest = ipc_right_dncancel_macro(space, port, - name, entry); - - assert(port->ip_srights > 0); - ip_unlock(port); - - if (bits & IE_BITS_MAREQUEST) - ipc_marequest_cancel(space, name); - - entry->ie_object = IO_NULL; - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - - if (dnrequest != IP_NULL) - ipc_notify_port_deleted(dnrequest, name); - - *objectp = (ipc_object_t) port; - break; - } else { - ipc_port_t port; - - /* - * Pulls a send right out of the space, - * making a send right if necessary. - * Doesn't operate on dead names. - */ - - if ((bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) - goto invalid_right; - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - if (ipc_right_check(space, port, name, entry)) { - if (bits & IE_BITS_COMPAT) - goto invalid_name; - - goto invalid_right; - } - /* port is locked and active */ - - is_write_unlock(space); - - if ((bits & MACH_PORT_TYPE_SEND) == 0) { - assert(IE_BITS_TYPE(bits) == - MACH_PORT_TYPE_RECEIVE); - assert(IE_BITS_UREFS(bits) == 0); - - port->ip_mscount++; - } - - port->ip_srights++; - ip_reference(port); - ip_unlock(port); - - *objectp = (ipc_object_t) port; - break; - } - - case MSG_TYPE_PORT_ALL: - if (dealloc) { - ipc_port_t port; - ipc_port_t dnrequest = IP_NULL; - ipc_port_t nsrequest = IP_NULL; - mach_port_mscount_t mscount = 0; /* '=0' to shut up lint */ - - /* - * Like MACH_MSG_TYPE_MOVE_RECEIVE, except that - * the space is always left without rights, - * so we kill send rights if necessary. - */ - - if ((bits & MACH_PORT_TYPE_RECEIVE) == 0) - goto invalid_right; - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - assert(ip_active(port)); - assert(port->ip_receiver_name == name); - assert(port->ip_receiver == space); - - dnrequest = ipc_right_dncancel_macro(space, port, - name, entry); - - if (bits & IE_BITS_MAREQUEST) - ipc_marequest_cancel(space, name); - - entry->ie_object = IO_NULL; - ipc_entry_dealloc(space, name, entry); - is_write_unlock(space); - - if (bits & MACH_PORT_TYPE_SEND) { - assert(IE_BITS_TYPE(bits) == - MACH_PORT_TYPE_SEND_RECEIVE); - assert(IE_BITS_UREFS(bits) > 0); - assert(port->ip_srights > 0); - - if (--port->ip_srights == 0) { - nsrequest = port->ip_nsrequest; - if (nsrequest != IP_NULL) { - port->ip_nsrequest = IP_NULL; - mscount = port->ip_mscount; - } - } - } - - ipc_port_clear_receiver(port); - - port->ip_receiver_name = MACH_PORT_NULL; - port->ip_destination = IP_NULL; - ip_unlock(port); - - if (nsrequest != IP_NULL) - ipc_notify_no_senders(nsrequest, mscount); - - if (dnrequest != IP_NULL) - ipc_notify_port_deleted(dnrequest, name); - - *objectp = (ipc_object_t) port; - break; - } else { - ipc_port_t port; - - /* - * Like MACH_MSG_TYPE_MOVE_RECEIVE, except that - * the space is always left with send rights, - * so we make a send right if necessary. - */ - - if ((bits & MACH_PORT_TYPE_RECEIVE) == 0) - goto invalid_right; - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - assert(ip_active(port)); - assert(port->ip_receiver_name == name); - assert(port->ip_receiver == space); - - if ((bits & MACH_PORT_TYPE_SEND) == 0) { - assert(IE_BITS_TYPE(bits) == - MACH_PORT_TYPE_RECEIVE); - assert(IE_BITS_UREFS(bits) == 0); - - /* ip_mscount will be cleared below */ - port->ip_srights++; - bits |= MACH_PORT_TYPE_SEND | 1; - } - - ipc_hash_insert(space, (ipc_object_t) port, - name, entry); - - entry->ie_bits = bits &~ MACH_PORT_TYPE_RECEIVE; - is_write_unlock(space); - - ipc_port_clear_receiver(port); /* clears ip_mscount */ - - port->ip_receiver_name = MACH_PORT_NULL; - port->ip_destination = IP_NULL; - ip_reference(port); - ip_unlock(port); - - *objectp = (ipc_object_t) port; - break; - } - - default: -#if MACH_ASSERT - assert(!"ipc_right_copyin_compat: strange rights"); -#else - panic("ipc_right_copyin_compat: strange rights"); -#endif - } - - return KERN_SUCCESS; - - invalid_right: - is_write_unlock(space); - return KERN_INVALID_RIGHT; - - invalid_name: - is_write_unlock(space); - return KERN_INVALID_NAME; -} - -/* - * Routine: ipc_right_copyin_header - * Purpose: - * Copyin a capability from a space. - * If successful, the caller gets a ref - * for the resulting object, which is always valid. - * The type of the acquired capability is returned. - * Conditions: - * The space is write-locked, and is unlocked upon return. - * The space must be active. - * Returns: - * KERN_SUCCESS Acquired a valid object. - * KERN_INVALID_RIGHT Name doesn't denote correct right. - * KERN_INVALID_NAME [MACH_IPC_COMPAT] - * Caller should pretend lookup of entry failed. - */ - -kern_return_t -ipc_right_copyin_header(space, name, entry, objectp, msgt_namep) - ipc_space_t space; - mach_port_t name; - ipc_entry_t entry; - ipc_object_t *objectp; - mach_msg_type_name_t *msgt_namep; -{ - ipc_entry_bits_t bits = entry->ie_bits; - mach_port_type_t type = IE_BITS_TYPE(bits); - - assert(space->is_active); - - switch (type) { - case MACH_PORT_TYPE_PORT_SET: - case MACH_PORT_TYPE_DEAD_NAME: - goto invalid_right; - - case MACH_PORT_TYPE_RECEIVE: { - ipc_port_t port; - - /* - * Like MACH_MSG_TYPE_MAKE_SEND. - */ - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - assert(ip_active(port)); - assert(port->ip_receiver_name == name); - assert(port->ip_receiver == space); - is_write_unlock(space); - - port->ip_mscount++; - port->ip_srights++; - ip_reference(port); - ip_unlock(port); - - *objectp = (ipc_object_t) port; - *msgt_namep = MACH_MSG_TYPE_PORT_SEND; - break; - } - - case MACH_PORT_TYPE_SEND: - case MACH_PORT_TYPE_SEND_RECEIVE: { - ipc_port_t port; - - /* - * Like MACH_MSG_TYPE_COPY_SEND, - * except that the port must be alive. - */ - - assert(IE_BITS_UREFS(bits) > 0); - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - if (ipc_right_check(space, port, name, entry)) { - if (bits & IE_BITS_COMPAT) - goto invalid_name; - - goto invalid_right; - } - /* port is locked and active */ - - assert(port->ip_srights > 0); - is_write_unlock(space); - - port->ip_srights++; - ip_reference(port); - ip_unlock(port); - - *objectp = (ipc_object_t) port; - *msgt_namep = MACH_MSG_TYPE_PORT_SEND; - break; - } - - case MACH_PORT_TYPE_SEND_ONCE: { - ipc_port_t port; - ipc_port_t dnrequest, notify; - - /* - * Like MACH_MSG_TYPE_MOVE_SEND_ONCE, - * except that the port must be alive - * and a port-deleted notification is generated. - */ - - assert(IE_BITS_UREFS(bits) == 1); - assert((bits & IE_BITS_MAREQUEST) == 0); - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - if (ipc_right_check(space, port, name, entry)) { - if (bits & IE_BITS_COMPAT) - goto invalid_name; - - goto invalid_right; - } - /* port is locked and active */ - - assert(port->ip_sorights > 0); - - dnrequest = ipc_right_dncancel_macro(space, port, name, entry); - ip_unlock(port); - - entry->ie_object = IO_NULL; - ipc_entry_dealloc(space, name, entry); - - notify = ipc_space_make_notify(space); - is_write_unlock(space); - - if (dnrequest != IP_NULL) - ipc_notify_port_deleted(dnrequest, name); - - if (IP_VALID(notify)) - ipc_notify_port_deleted_compat(notify, name); - - *objectp = (ipc_object_t) port; - *msgt_namep = MACH_MSG_TYPE_PORT_SEND_ONCE; - break; - } - - default: -#if MACH_ASSERT - assert(!"ipc_right_copyin_header: strange rights"); -#else - panic("ipc_right_copyin_header: strange rights"); -#endif - } - - return KERN_SUCCESS; - - invalid_right: - is_write_unlock(space); - return KERN_INVALID_RIGHT; - - invalid_name: - is_write_unlock(space); - return KERN_INVALID_NAME; -} - -#endif /* MACH_IPC_COMPAT */ diff --git a/ipc/ipc_right.h b/ipc/ipc_right.h index 4b937c0..fe0a088 100644 --- a/ipc/ipc_right.h +++ b/ipc/ipc_right.h @@ -108,15 +108,4 @@ extern kern_return_t ipc_right_rename(/* ipc_space_t, mach_port_t, ipc_entry_t, mach_port_t, ipc_entry_t */); -#if MACH_IPC_COMPAT - -extern kern_return_t -ipc_right_copyin_compat(/* ipc_space_t, mach_port_t, ipc_entry_t, - mach_msg_type_name_t, boolean_t, ipc_object_t * */); - -extern kern_return_t -ipc_right_copyin_header(/* ipc_space_t, mach_port_t, ipc_entry_t, - ipc_object_t *, mach_msg_type_name_t * */); - -#endif /* MACH_IPC_COMPAT */ #endif /* _IPC_IPC_RIGHT_H_ */ diff --git a/ipc/ipc_space.c b/ipc/ipc_space.c index 444f400..0f50f15 100644 --- a/ipc/ipc_space.c +++ b/ipc/ipc_space.c @@ -149,33 +149,6 @@ ipc_space_create( space->is_tree_small = 0; space->is_tree_hash = 0; -#if MACH_IPC_COMPAT - { - mach_port_t name; - ipc_port_t port; - kern_return_t kr; - - /* - * ipc_port_alloc_compat probably won't look at is_notify, - * but make sure all fields have sane values anyway. - */ - - space->is_notify = IP_NULL; - - kr = ipc_port_alloc_compat(space, &name, &port); - if (kr != KERN_SUCCESS) { - ipc_space_destroy(space); - is_release(space); - return kr; - } - - ip_reference(port); - port->ip_srights++; - ip_unlock(port); - space->is_notify = port; - } -#endif /* MACH_IPC_COMPAT */ - *spacep = space; return KERN_SUCCESS; } @@ -298,11 +271,6 @@ ipc_space_destroy( } ipc_splay_traverse_finish(&space->is_tree); -#if MACH_IPC_COMPAT - if (IP_VALID(space->is_notify)) - ipc_port_release_send(space->is_notify); -#endif /* MACH_IPC_COMPAT */ - /* * Because the space is now dead, * we must release the "active" reference for it. diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h index 6d2ed82..50f5d5e 100644 --- a/ipc/ipc_space.h +++ b/ipc/ipc_space.h @@ -76,10 +76,6 @@ struct ipc_space { ipc_entry_num_t is_tree_total; /* number of entries in the tree */ ipc_entry_num_t is_tree_small; /* # of small entries in the tree */ ipc_entry_num_t is_tree_hash; /* # of hashed entries in the tree */ - -#if MACH_IPC_COMPAT - struct ipc_port *is_notify; /* notification port */ -#endif /* MACH_IPC_COMPAT */ }; #define IS_NULL ((ipc_space_t) 0) @@ -136,23 +132,4 @@ kern_return_t ipc_space_create(/* ipc_table_size_t, ipc_space_t * */); kern_return_t ipc_space_create_special(struct ipc_space **); void ipc_space_destroy(struct ipc_space *); -#if MACH_IPC_COMPAT - -/* - * Routine: ipc_space_make_notify - * Purpose: - * Given a space, return a send right for a notification. - * May return IP_NULL/IP_DEAD. - * Conditions: - * The space is locked (read or write) and active. - * - * ipc_port_t - * ipc_space_make_notify(space) - * ipc_space_t space; - */ - -#define ipc_space_make_notify(space) \ - ipc_port_copy_send(space->is_notify) - -#endif /* MACH_IPC_COMPAT */ #endif /* _IPC_IPC_SPACE_H_ */ diff --git a/ipc/mach_debug.c b/ipc/mach_debug.c index acb9f97..9854cec 100644 --- a/ipc/mach_debug.c +++ b/ipc/mach_debug.c @@ -381,11 +381,7 @@ mach_port_space_info( iin->iin_name = MACH_PORT_MAKEB(index, bits); iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE; -#if MACH_IPC_COMPAT - iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE; -#else /* MACH_IPC_COMPAT */ iin->iin_compat = FALSE; -#endif /* MACH_IPC_COMPAT */ iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE; iin->iin_type = IE_BITS_TYPE(bits); iin->iin_urefs = IE_BITS_UREFS(bits); @@ -406,11 +402,7 @@ mach_port_space_info( iin->iin_name = tentry->ite_name; iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE; -#if MACH_IPC_COMPAT - iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE; -#else /* MACH_IPC_COMPAT */ iin->iin_compat = FALSE; -#endif /* MACH_IPC_COMPAT */ iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE; iin->iin_type = IE_BITS_TYPE(bits); iin->iin_urefs = IE_BITS_UREFS(bits); 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 */ diff --git a/ipc/mach_msg.h b/ipc/mach_msg.h index 021ddc5..f7d22e3 100644 --- a/ipc/mach_msg.h +++ b/ipc/mach_msg.h @@ -57,10 +57,4 @@ mach_msg_continue(); extern boolean_t mach_msg_interrupt(/* thread_t */); -#if MACH_IPC_COMPAT - -extern void -msg_receive_continue(); - -#endif /* MACH_IPC_COMPAT */ #endif /* _IPC_MACH_MSG_H_ */ diff --git a/ipc/mach_port.c b/ipc/mach_port.c index f522cac..c9f24c5 100644 --- a/ipc/mach_port.c +++ b/ipc/mach_port.c @@ -102,11 +102,6 @@ mach_port_names_helper( ip_unlock(port); if (died) { -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - return; -#endif /* MACH_IPC_COMPAT */ - /* pretend this is a dead-name entry */ bits &= ~(IE_BITS_TYPE_MASK|IE_BITS_MAREQUEST); @@ -118,11 +113,6 @@ mach_port_names_helper( } type = IE_BITS_TYPE(bits); -#if MACH_IPC_COMPAT - if (bits & IE_BITS_COMPAT) - type |= MACH_PORT_TYPE_COMPAT; - else -#endif /* MACH_IPC_COMPAT */ if (request != 0) type |= MACH_PORT_TYPE_DNREQUEST; if (bits & IE_BITS_MAREQUEST) @@ -1228,19 +1218,6 @@ mach_port_request_notification( ipc_port_pdrequest(port, notify, &previous); /* port is unlocked */ -#if MACH_IPC_COMPAT - /* - * If previous was a send right instead of a send-once - * right, we can't return it in the reply message. - * So destroy it instead. - */ - - if ((previous != IP_NULL) && ip_pdsendp(previous)) { - ipc_port_release_send(ip_pdsend(previous)); - previous = IP_NULL; - } -#endif /* MACH_IPC_COMPAT */ - *previousp = previous; break; } @@ -1567,939 +1544,3 @@ mach_port_set_syscall_right(task, name) } #endif #endif /* MIGRATING_THREADS */ - -#if MACH_IPC_COMPAT - -/* - * Routine: port_translate_compat - * Purpose: - * Converts a name to a receive right. - * Conditions: - * Nothing locked. If successful, the port - * is returned locked and active. - * Returns: - * KERN_SUCCESS Port is returned. - * KERN_INVALID_ARGUMENT The space is dead. - * KERN_INVALID_ARGUMENT Name doesn't denote port rights. - * KERN_NOT_RECEIVER Name denotes send, not receive, rights. - * KERN_NOT_RECEIVER Name denotes a send-once right. - * KERN_NOT_RECEIVER Name denotes a dead name. - */ - -kern_return_t -port_translate_compat(space, name, portp) - ipc_space_t space; - mach_port_t name; - ipc_port_t *portp; -{ - ipc_entry_t entry; - mach_port_type_t type; - mach_port_urefs_t urefs; - ipc_port_t port; - kern_return_t kr; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - /* space is write-locked and active */ - - kr = ipc_right_info(space, name, entry, &type, &urefs); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; /* space is unlocked */ - - if ((type & (MACH_PORT_TYPE_RECEIVE)) == 0) { - is_write_unlock(space); - if (type & MACH_PORT_TYPE_PORT_OR_DEAD) - return KERN_NOT_RECEIVER; - else - return KERN_INVALID_ARGUMENT; - } - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - is_write_unlock(space); - assert(ip_active(port)); - - *portp = port; - return KERN_SUCCESS; -} - -/* - * Routine: convert_port_type - * Purpose: - * Convert a new mach_port_type_t to an old value. - * Note send-once rights and dead names get - * represented as send rights. The extra info - * bits get dropped. - */ - -mach_port_type_t -convert_port_type(type) - mach_port_type_t type; -{ - switch (type & MACH_PORT_TYPE_ALL_RIGHTS) { - case MACH_PORT_TYPE_SEND: - case MACH_PORT_TYPE_SEND_ONCE: - case MACH_PORT_TYPE_DEAD_NAME: - return PORT_TYPE_SEND; - - case MACH_PORT_TYPE_RECEIVE: - case MACH_PORT_TYPE_SEND_RECEIVE: - return PORT_TYPE_RECEIVE_OWN; - - case MACH_PORT_TYPE_PORT_SET: - return PORT_TYPE_SET; - - default: -#if MACH_ASSERT - assert(!"convert_port_type: strange port type"); -#else - panic("convert_port_type: strange port type"); -#endif - } -} - -/* - * Routine: port_names [kernel call] - * Purpose: - * Retrieve all the names in the task's port name space. - * As a (major) convenience, return port type information. - * The port name space includes port sets. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Retrieved names. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * Additions: - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_names(space, namesp, namesCnt, typesp, typesCnt) - ipc_space_t space; - mach_port_t **namesp; - mach_msg_type_number_t *namesCnt; - mach_port_type_t **typesp; - mach_msg_type_number_t *typesCnt; -{ - kern_return_t kr; - - kr = mach_port_names(space, namesp, namesCnt, typesp, typesCnt); - if (kr == KERN_SUCCESS) { - ipc_entry_num_t actual = (ipc_entry_num_t) *typesCnt; - mach_port_type_t *types; - ipc_entry_num_t i; - - vm_map_copy_t copy = (vm_map_copy_t) *typesp; - vm_offset_t addr; - vm_size_t size = round_page(actual * sizeof(mach_port_type_t)); - - /* convert copy object back to something we can use */ - - kr = vm_map_copyout(ipc_kernel_map, &addr, copy); - if (kr != KERN_SUCCESS) { - vm_map_copy_discard((vm_map_copy_t) *typesp); - vm_map_copy_discard((vm_map_copy_t) *namesp); - return KERN_RESOURCE_SHORTAGE; - } - - types = (mach_port_type_t *) addr; - - for (i = 0; i < actual; i++) - types[i] = convert_port_type(types[i]); - - /* convert memory back into a copy object */ - - kr = vm_map_copyin(ipc_kernel_map, addr, size, - TRUE, ©); - assert(kr == KERN_SUCCESS); - - *typesp = (mach_port_type_t *) copy; - } else if (kr != KERN_RESOURCE_SHORTAGE) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_type [kernel call] - * Purpose: - * Return type of the capability named. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Retrieved type. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT The name doesn't denote a right. - */ - -kern_return_t -port_type(space, name, typep) - ipc_space_t space; - mach_port_t name; - mach_port_type_t *typep; -{ - mach_port_type_t type; - kern_return_t kr; - - kr = mach_port_type(space, name, &type); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - - *typep = convert_port_type(type); - return KERN_SUCCESS; -} - -/* - * Routine: port_rename [kernel call] - * Purpose: - * Change the name of a capability. - * The new name can't be in use. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Retrieved type. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT The new name is reserved. - * KERN_NAME_EXISTS The new name already denotes a right. - * KERN_INVALID_ARGUMENT The old name doesn't denote a right. - */ - -kern_return_t -port_rename(space, old_name, new_name) - ipc_space_t space; - mach_port_t old_name; - mach_port_t new_name; -{ - kern_return_t kr; - - kr = mach_port_rename(space, old_name, new_name); - if ((kr != KERN_SUCCESS) && (kr != KERN_NAME_EXISTS)) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_allocate [kernel call] - * Purpose: - * Allocate a new port, giving all rights to "task". - * - * Returns in "port_name" the task's local name for the port. - * Doesn't return a reference to the port. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Allocated a port. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_allocate(space, namep) - ipc_space_t space; - mach_port_t *namep; -{ - ipc_port_t port; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_port_alloc_compat(space, namep, &port); - if (kr == KERN_SUCCESS) - ip_unlock(port); - else if (kr != KERN_RESOURCE_SHORTAGE) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_deallocate [kernel call] - * Purpose: - * Delete port rights (send and receive) from a task. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Deallocated the port right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port right. - * Additions: - * KERN_SUCCESS Deallocated a send-once right. - * KERN_SUCCESS Destroyed a dead name. - */ - -kern_return_t -port_deallocate(space, name) - ipc_space_t space; - mach_port_t name; -{ - ipc_entry_t entry; - mach_port_type_t type; - mach_port_urefs_t urefs; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - /* space is write-locked and active */ - - /* - * We serialize with port destruction with the - * ipc_right_info call, not ipc_right_destroy. - * After ipc_right_info, we pretend that the - * port doesn't get destroyed. - */ - - kr = ipc_right_info(space, name, entry, &type, &urefs); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; /* space is unlocked */ - - if ((type & (MACH_PORT_TYPE_PORT_OR_DEAD)) == 0) { - is_write_unlock(space); - return KERN_INVALID_ARGUMENT; - } - - (void) ipc_right_destroy(space, name, entry); - /* space is unlocked */ - - return KERN_SUCCESS; -} - -/* - * Routine: port_set_backlog [kernel call] - * Purpose: - * Change the queueing backlog on "port_name" to "backlog"; - * the specified "task" must be the current receiver. - * - * Valid backlog values are 0 < backlog <= PORT_BACKLOG_MAX. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Set the backlog. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port right. - * KERN_NOT_RECEIVER Name denotes send rights, not receive. - * KERN_INVALID_ARGUMENT Backlog value is invalid. - * Additions: - * KERN_NOT_RECEIVER Name denotes a send-once right. - * KERN_NOT_RECEIVER Name denotes a dead name. - */ - -kern_return_t -port_set_backlog(space, name, backlog) - ipc_space_t space; - mach_port_t name; - int backlog; -{ - ipc_port_t port; - kern_return_t kr; - - if ((space == IS_NULL) || - (backlog <= 0) || - (backlog > PORT_BACKLOG_MAX)) - return KERN_INVALID_ARGUMENT; - - kr = port_translate_compat(space, name, &port); - if (kr != KERN_SUCCESS) - return kr; - /* port is locked and active */ - - ipc_port_set_qlimit(port, (mach_port_msgcount_t) backlog); - - ip_unlock(port); - return KERN_SUCCESS; -} - -/* - * Routine: port_set_backup [kernel call] - * Purpose: - * Changes the backup port for the the named port. - * The specified "task" must be the current receiver. - * Returns the old backup port, if any. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Set the backup. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port right. - * KERN_NOT_RECEIVER Name denotes send rights, not receive. - * Additions: - * KERN_NOT_RECEIVER Name denotes a send-once right. - * KERN_NOT_RECEIVER Name denotes a dead name. - */ - -kern_return_t -port_set_backup(space, name, backup, previousp) - ipc_space_t space; - mach_port_t name; - ipc_port_t backup; - ipc_port_t *previousp; -{ - ipc_port_t port, previous; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - if (backup == IP_DEAD) - backup = IP_NULL; - else if (backup != IP_NULL) - backup = ip_pdsendm(backup); - - kr = port_translate_compat(space, name, &port); - if (kr != KERN_SUCCESS) - return kr; - /* port is locked and active */ - - ipc_port_pdrequest(port, backup, &previous); - /* port is unlocked */ - - /* - * If previous was a send-once right instead of a send - * right, we can't return it in the reply message. - * So get rid of it in a notification instead. - */ - - if (previous != IP_NULL) { - if (ip_pdsendp(previous)) - previous = ip_pdsend(previous); - else { - ipc_notify_send_once(previous); - previous = IP_NULL; - } - } - - *previousp = previous; - return KERN_SUCCESS; -} - -/* - * Routine: port_status [kernel call] - * Purpose: - * Returns statistics related to "port_name", as seen by "task". - * Only the receiver for a given port will see true message - * counts. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Retrieved status. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port right. - * Additions: - * KERN_SUCCESS Send-once right. - * KERN_SUCCESS Dead name. - */ - -kern_return_t -port_status(space, name, enabledp, num_msgs, backlog, - ownership, receive_rights) - ipc_space_t space; - mach_port_t name; - mach_port_t *enabledp; - int *num_msgs; - int *backlog; - boolean_t *ownership; - boolean_t *receive_rights; -{ - ipc_entry_t entry; - mach_port_type_t type; - mach_port_urefs_t urefs; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - /* space is write-locked and active */ - - kr = ipc_right_info(space, name, entry, &type, &urefs); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; /* space is unlocked */ - - if ((type & MACH_PORT_TYPE_PORT_OR_DEAD) == 0) { - is_write_unlock(space); - return KERN_INVALID_ARGUMENT; - } - - if (type & MACH_PORT_TYPE_RECEIVE) { - mach_port_t enabled; - mach_port_msgcount_t qlimit; - mach_port_msgcount_t msgcount; - ipc_port_t port; - - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - ip_lock(port); - is_write_unlock(space); - assert(ip_active(port)); - - if (port->ip_pset != IPS_NULL) { - ipc_pset_t pset = port->ip_pset; - - ips_lock(pset); - if (!ips_active(pset)) { - ipc_pset_remove(pset, port); - ips_check_unlock(pset); - enabled = MACH_PORT_NULL; - } else { - enabled = pset->ips_local_name; - ips_unlock(pset); - assert(MACH_PORT_VALID(enabled)); - } - } else - enabled = MACH_PORT_NULL; - - qlimit = port->ip_qlimit; - msgcount = port->ip_msgcount; - ip_unlock(port); - - *ownership = TRUE; - *receive_rights = TRUE; - *enabledp = enabled; - *num_msgs = (int) msgcount; - *backlog = (int) qlimit; - } else { - is_write_unlock(space); - - *ownership = FALSE; - *receive_rights = FALSE; - *enabledp = MACH_PORT_NULL; - *num_msgs = -1; - *backlog = 0; - } - - return KERN_SUCCESS; -} - -/* - * Routine: port_set_allocate [kernel call] - * Purpose: - * Create a new port set, give rights to task, and - * return task's local name for the set. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Allocated a port set. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_set_allocate(space, namep) - ipc_space_t space; - mach_port_t *namep; -{ - ipc_pset_t pset; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_pset_alloc(space, namep, &pset); - if (kr == KERN_SUCCESS) - ips_unlock(pset); - else if (kr != KERN_RESOURCE_SHORTAGE) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_set_deallocate [kernel call] - * Purpose: - * Destroys the task's port set. If there are any - * receive rights in the set, they are removed. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Deallocated the port set. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port set. - */ - -kern_return_t -port_set_deallocate(space, name) - ipc_space_t space; - mach_port_t name; -{ - ipc_entry_t entry; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return kr; - /* space is write-locked and active */ - - if ((entry->ie_bits & MACH_PORT_TYPE_PORT_SET) == 0) { - is_write_unlock(space); - return KERN_INVALID_ARGUMENT; - } - - kr = ipc_right_destroy(space, name, entry); - /* space is unlocked */ - assert(kr == KERN_SUCCESS); - return kr; -} - -/* - * Routine: port_set_add [kernel call] - * Purpose: - * Moves receive rights into the port set. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Moved the receive right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT port_name doesn't denote port rights. - * KERN_NOT_RECEIVER port_name doesn't denote receive right. - * KERN_INVALID_ARGUMENT set_name doesn't denote a port set. - * Additions: - * KERN_NOT_RECEIVER port_name denotes a send-once right. - * KERN_NOT_RECEIVER port_name denotes a dead name. - */ - -kern_return_t -port_set_add(space, set_name, port_name) - ipc_space_t space; - mach_port_t set_name; - mach_port_t port_name; -{ - ipc_entry_t entry; - mach_port_type_t type; - mach_port_urefs_t urefs; - ipc_port_t port; - ipc_pset_t pset; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_right_lookup_write(space, port_name, &entry); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - /* space is write-locked and active */ - - /* use ipc_right_info to check for dead compat entries */ - - kr = ipc_right_info(space, port_name, entry, &type, &urefs); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; /* space is unlocked */ - - if ((type & MACH_PORT_TYPE_RECEIVE) == 0) { - is_write_unlock(space); - if (type & MACH_PORT_TYPE_PORT_OR_DEAD) - return KERN_NOT_RECEIVER; - else - return KERN_INVALID_ARGUMENT; - } - - is_write_to_read_lock(space); - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - entry = ipc_entry_lookup(space, set_name); - if ((entry == IE_NULL) || - ((entry->ie_bits & MACH_PORT_TYPE_PORT_SET) == 0)) { - is_read_unlock(space); - return KERN_INVALID_ARGUMENT; - } - - pset = (ipc_pset_t) entry->ie_object; - assert(pset != IPS_NULL); - - kr = ipc_pset_move(space, port, pset); - /* space is unlocked */ - assert(kr == KERN_SUCCESS); - return kr; -} - -/* - * Routine: port_set_remove [kernel call] - * Purpose: - * Removes the receive rights from the set they are in. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Removed the receive right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port right. - * KERN_NOT_RECEIVER Name denotes send rights, not receive. - * KERN_NOT_IN_SET Port isn't in a port set. - * Additions: - * KERN_NOT_RECEIVER Name denotes a send-once right. - * KERN_NOT_RECEIVER Name denotes a dead name. - */ - -kern_return_t -port_set_remove(space, name) - ipc_space_t space; - mach_port_t name; -{ - ipc_entry_t entry; - mach_port_type_t type; - mach_port_urefs_t urefs; - ipc_port_t port; - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_right_lookup_write(space, name, &entry); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; - /* space is write-locked and active */ - - /* use ipc_right_info to check for dead compat entries */ - - kr = ipc_right_info(space, name, entry, &type, &urefs); - if (kr != KERN_SUCCESS) - return KERN_INVALID_ARGUMENT; /* space is unlocked */ - - if ((type & (MACH_PORT_TYPE_RECEIVE)) == 0) { - is_write_unlock(space); - if (type & MACH_PORT_TYPE_PORT_OR_DEAD) - return KERN_NOT_RECEIVER; - else - return KERN_INVALID_ARGUMENT; - } - - is_write_to_read_lock(space); - port = (ipc_port_t) entry->ie_object; - assert(port != IP_NULL); - - kr = ipc_pset_move(space, port, IPS_NULL); - /* space is unlocked */ - return kr; -} - -/* - * Routine: port_set_status [kernel call] - * Purpose: - * Retrieve list of members of a port set. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Retrieved port set status. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote a port set. - * Additions: - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_set_status(space, name, members, membersCnt) - ipc_space_t space; - mach_port_t name; - mach_port_t **members; - mach_msg_type_number_t *membersCnt; -{ - kern_return_t kr; - - kr = mach_port_get_set_status(space, name, members, membersCnt); - if ((kr != KERN_SUCCESS) && (kr != KERN_RESOURCE_SHORTAGE)) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_insert_send [kernel call] - * Purpose: - * Inserts send rights to a port into a task, - * at a given name. The name must not be in use. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Inserted send right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Port is null or dead. - * KERN_INVALID_ARGUMENT Name is reserved. - * KERN_NAME_EXISTS Name already denotes a right. - * KERN_FAILURE Task already has rights for the port. - * Additions: - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_insert_send(space, port, name) - ipc_space_t space; - ipc_port_t port; - mach_port_t name; -{ - kern_return_t kr; - - if ((space == IS_NULL) || - !MACH_PORT_VALID(name) || - !IP_VALID(port)) - return KERN_INVALID_ARGUMENT; - - kr = ipc_object_copyout_name_compat(space, (ipc_object_t) port, - MACH_MSG_TYPE_PORT_SEND, name); - switch (kr) { - case KERN_SUCCESS: - case KERN_NAME_EXISTS: - case KERN_RESOURCE_SHORTAGE: - break; - - case KERN_RIGHT_EXISTS: - kr = KERN_FAILURE; - break; - - default: - kr = KERN_INVALID_ARGUMENT; - break; - } - - return kr; -} - -/* - * Routine: port_extract_send [kernel call] - * Purpose: - * Extracts send rights from "task"'s "his_name" port. - * The task is left with no rights for the port. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Extracted send right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote pure send rights. - */ - -kern_return_t -port_extract_send(space, name, portp) - ipc_space_t space; - mach_port_t name; - ipc_port_t *portp; -{ - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_object_copyin_compat(space, name, - MSG_TYPE_PORT, TRUE, - (ipc_object_t *) portp); - if (kr != KERN_SUCCESS) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -/* - * Routine: port_insert_receive [kernel call] - * Purpose: - * Inserts receive/ownership rights to a port into a task, - * at a given name. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Inserted receive right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Port is null. (Can't be dead.) - * KERN_INVALID_ARGUMENT Name is reserved. - * KERN_NAME_EXISTS Name already denotes a right. - * KERN_FAILURE Task already has rights for the port. - * Additions: - * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. - */ - -kern_return_t -port_insert_receive(space, port, name) - ipc_space_t space; - ipc_port_t port; - mach_port_t name; -{ - kern_return_t kr; - - if ((space == IS_NULL) || - !MACH_PORT_VALID(name) || - !IP_VALID(port)) - return KERN_INVALID_ARGUMENT; - - kr = ipc_object_copyout_name_compat(space, (ipc_object_t) port, - MACH_MSG_TYPE_PORT_RECEIVE, name); - switch (kr) { - case KERN_SUCCESS: - case KERN_NAME_EXISTS: - case KERN_RESOURCE_SHORTAGE: - break; - - case KERN_RIGHT_EXISTS: - kr = KERN_FAILURE; - break; - - default: - kr = KERN_INVALID_ARGUMENT; - break; - } - - return kr; -} - -/* - * Routine: port_extract_receive [kernel call] - * Purpose: - * Extracts receive/ownership rights - * from "task"'s "his_name" port. - * - * The task is left with no rights for the port. - * Conditions: - * Nothing locked. - * Returns: - * KERN_SUCCESS Extracted receive right. - * KERN_INVALID_ARGUMENT Task is null. - * KERN_INVALID_ARGUMENT Task is not active. - * KERN_INVALID_ARGUMENT Name doesn't denote receive rights. - */ - -kern_return_t -port_extract_receive(space, name, portp) - ipc_space_t space; - mach_port_t name; - ipc_port_t *portp; -{ - kern_return_t kr; - - if (space == IS_NULL) - return KERN_INVALID_ARGUMENT; - - kr = ipc_object_copyin_compat(space, name, - MSG_TYPE_PORT_ALL, TRUE, - (ipc_object_t *) portp); - if (kr != KERN_SUCCESS) - kr = KERN_INVALID_ARGUMENT; - - return kr; -} - -#endif /* MACH_IPC_COMPAT */ |