2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
59 * File: ipc/ipc_object.c
63 * Functions to manipulate IPC objects.
68 #include <mach/mach_types.h>
69 #include <mach/boolean.h>
70 #include <mach/kern_return.h>
71 #include <mach/port.h>
72 #include <mach/message.h>
74 #include <kern/kern_types.h>
75 #include <kern/misc_protos.h>
77 #include <ipc/ipc_types.h>
79 #include <ipc/ipc_space.h>
80 #include <ipc/ipc_entry.h>
81 #include <ipc/ipc_object.h>
82 #include <ipc/ipc_hash.h>
83 #include <ipc/ipc_right.h>
84 #include <ipc/ipc_notify.h>
85 #include <ipc/ipc_pset.h>
87 zone_t ipc_object_zones
[IOT_NUMBER
];
90 * Routine: ipc_object_reference
92 * Take a reference to an object.
100 assert(object
->io_references
> 0);
101 io_reference(object
);
106 * Routine: ipc_object_release
108 * Release a reference to an object.
116 assert(object
->io_references
> 0);
118 io_check_unlock(object
);
122 * Routine: ipc_object_translate
124 * Look up an object in a space.
126 * Nothing locked before. If successful, the object
127 * is returned locked. The caller doesn't get a ref.
129 * KERN_SUCCESS Object returned locked.
130 * KERN_INVALID_TASK The space is dead.
131 * KERN_INVALID_NAME The name doesn't denote a right.
132 * KERN_INVALID_RIGHT Name doesn't denote the correct right.
136 ipc_object_translate(
138 mach_port_name_t name
,
139 mach_port_right_t right
,
140 ipc_object_t
*objectp
)
146 kr
= ipc_right_lookup_read(space
, name
, &entry
);
147 if (kr
!= KERN_SUCCESS
)
149 /* space is read-locked and active */
151 if ((entry
->ie_bits
& MACH_PORT_TYPE(right
)) == MACH_PORT_TYPE_NONE
) {
152 is_read_unlock(space
);
153 return KERN_INVALID_RIGHT
;
156 object
= entry
->ie_object
;
157 assert(object
!= IO_NULL
);
160 is_read_unlock(space
);
167 * Routine: ipc_object_translate_two
169 * Look up two objects in a space.
171 * Nothing locked before. If successful, the objects
172 * are returned locked. The caller doesn't get a ref.
174 * KERN_SUCCESS Objects returned locked.
175 * KERN_INVALID_TASK The space is dead.
176 * KERN_INVALID_NAME A name doesn't denote a right.
177 * KERN_INVALID_RIGHT A name doesn't denote the correct right.
181 ipc_object_translate_two(
183 mach_port_name_t name1
,
184 mach_port_right_t right1
,
185 ipc_object_t
*objectp1
,
186 mach_port_name_t name2
,
187 mach_port_right_t right2
,
188 ipc_object_t
*objectp2
)
195 kr
= ipc_right_lookup_two_read(space
, name1
, &entry1
, name2
, &entry2
);
196 if (kr
!= KERN_SUCCESS
)
198 /* space is read-locked and active */
200 if ((entry1
->ie_bits
& MACH_PORT_TYPE(right1
)) == MACH_PORT_TYPE_NONE
) {
201 is_read_unlock(space
);
202 return KERN_INVALID_RIGHT
;
205 if ((entry2
->ie_bits
& MACH_PORT_TYPE(right2
)) == MACH_PORT_TYPE_NONE
) {
206 is_read_unlock(space
);
207 return KERN_INVALID_RIGHT
;
210 object
= entry1
->ie_object
;
211 assert(object
!= IO_NULL
);
215 object
= entry2
->ie_object
;
216 assert(object
!= IO_NULL
);
220 is_read_unlock(space
);
225 * Routine: ipc_object_alloc_dead
227 * Allocate a dead-name entry.
231 * KERN_SUCCESS The dead name is allocated.
232 * KERN_INVALID_TASK The space is dead.
233 * KERN_NO_SPACE No room for an entry in the space.
234 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
238 ipc_object_alloc_dead(
240 mach_port_name_t
*namep
)
245 kr
= ipc_entry_alloc(space
, namep
, &entry
);
246 if (kr
!= KERN_SUCCESS
)
248 /* space is write-locked */
250 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
252 assert(entry
->ie_object
== IO_NULL
);
253 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
255 is_write_unlock(space
);
260 * Routine: ipc_object_alloc_dead_name
262 * Allocate a dead-name entry, with a specific name.
266 * KERN_SUCCESS The dead name is allocated.
267 * KERN_INVALID_TASK The space is dead.
268 * KERN_NAME_EXISTS The name already denotes a right.
269 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
273 ipc_object_alloc_dead_name(
275 mach_port_name_t name
)
280 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
281 if (kr
!= KERN_SUCCESS
)
283 /* space is write-locked */
285 if (ipc_right_inuse(space
, name
, entry
))
286 return KERN_NAME_EXISTS
;
288 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
290 assert(entry
->ie_object
== IO_NULL
);
291 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
293 is_write_unlock(space
);
298 * Routine: ipc_object_alloc
300 * Allocate an object.
302 * Nothing locked. If successful, the object is returned locked.
303 * The caller doesn't get a reference for the object.
305 * KERN_SUCCESS The object is allocated.
306 * KERN_INVALID_TASK The space is dead.
307 * KERN_NO_SPACE No room for an entry in the space.
308 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
314 ipc_object_type_t otype
,
315 mach_port_type_t type
,
316 mach_port_urefs_t urefs
,
317 mach_port_name_t
*namep
,
318 ipc_object_t
*objectp
)
324 assert(otype
< IOT_NUMBER
);
325 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
326 assert(type
!= MACH_PORT_TYPE_NONE
);
327 assert(urefs
<= MACH_PORT_UREFS_MAX
);
329 object
= io_alloc(otype
);
330 if (object
== IO_NULL
)
331 return KERN_RESOURCE_SHORTAGE
;
333 if (otype
== IOT_PORT
) {
334 ipc_port_t port
= (ipc_port_t
)object
;
336 bzero((char *)port
, sizeof(*port
));
337 } else if (otype
== IOT_PORT_SET
) {
338 ipc_pset_t pset
= (ipc_pset_t
)object
;
340 bzero((char *)pset
, sizeof(*pset
));
343 io_lock_init(object
);
344 *namep
= (mach_port_name_t
)object
;
345 kr
= ipc_entry_alloc(space
, namep
, &entry
);
346 if (kr
!= KERN_SUCCESS
) {
347 io_free(otype
, object
);
350 /* space is write-locked */
352 entry
->ie_bits
|= type
| urefs
;
353 entry
->ie_object
= object
;
356 is_write_unlock(space
);
358 object
->io_references
= 1; /* for entry, not caller */
359 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
366 * Routine: ipc_object_alloc_name
368 * Allocate an object, with a specific name.
370 * Nothing locked. If successful, the object is returned locked.
371 * The caller doesn't get a reference for the object.
373 * KERN_SUCCESS The object is allocated.
374 * KERN_INVALID_TASK The space is dead.
375 * KERN_NAME_EXISTS The name already denotes a right.
376 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
380 ipc_object_alloc_name(
382 ipc_object_type_t otype
,
383 mach_port_type_t type
,
384 mach_port_urefs_t urefs
,
385 mach_port_name_t name
,
386 ipc_object_t
*objectp
)
392 assert(otype
< IOT_NUMBER
);
393 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
394 assert(type
!= MACH_PORT_TYPE_NONE
);
395 assert(urefs
<= MACH_PORT_UREFS_MAX
);
397 object
= io_alloc(otype
);
398 if (object
== IO_NULL
)
399 return KERN_RESOURCE_SHORTAGE
;
401 if (otype
== IOT_PORT
) {
402 ipc_port_t port
= (ipc_port_t
)object
;
404 bzero((char *)port
, sizeof(*port
));
405 } else if (otype
== IOT_PORT_SET
) {
406 ipc_pset_t pset
= (ipc_pset_t
)object
;
408 bzero((char *)pset
, sizeof(*pset
));
411 io_lock_init(object
);
412 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
413 if (kr
!= KERN_SUCCESS
) {
414 io_free(otype
, object
);
417 /* space is write-locked */
419 if (ipc_right_inuse(space
, name
, entry
)) {
420 io_free(otype
, object
);
421 return KERN_NAME_EXISTS
;
424 entry
->ie_bits
|= type
| urefs
;
425 entry
->ie_object
= object
;
428 is_write_unlock(space
);
430 object
->io_references
= 1; /* for entry, not caller */
431 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
438 * Routine: ipc_object_copyin_type
440 * Convert a send type name to a received type name.
444 ipc_object_copyin_type(
445 mach_msg_type_name_t msgt_name
)
449 case MACH_MSG_TYPE_MOVE_RECEIVE
:
450 case MACH_MSG_TYPE_COPY_RECEIVE
:
451 return MACH_MSG_TYPE_PORT_RECEIVE
;
453 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
454 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
455 return MACH_MSG_TYPE_PORT_SEND_ONCE
;
457 case MACH_MSG_TYPE_MOVE_SEND
:
458 case MACH_MSG_TYPE_MAKE_SEND
:
459 case MACH_MSG_TYPE_COPY_SEND
:
460 return MACH_MSG_TYPE_PORT_SEND
;
463 return MACH_MSG_TYPE_PORT_NONE
;
468 * Routine: ipc_object_copyin
470 * Copyin a capability from a space.
471 * If successful, the caller gets a ref
472 * for the resulting object, unless it is IO_DEAD.
476 * KERN_SUCCESS Acquired an object, possibly IO_DEAD.
477 * KERN_INVALID_TASK The space is dead.
478 * KERN_INVALID_NAME Name doesn't exist in space.
479 * KERN_INVALID_RIGHT Name doesn't denote correct right.
485 mach_port_name_t name
,
486 mach_msg_type_name_t msgt_name
,
487 ipc_object_t
*objectp
)
494 * Could first try a read lock when doing
495 * MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND,
496 * and MACH_MSG_TYPE_MAKE_SEND_ONCE.
499 kr
= ipc_right_lookup_write(space
, name
, &entry
);
500 if (kr
!= KERN_SUCCESS
)
502 /* space is write-locked and active */
504 kr
= ipc_right_copyin(space
, name
, entry
,
507 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
508 ipc_entry_dealloc(space
, name
, entry
);
509 is_write_unlock(space
);
511 if ((kr
== KERN_SUCCESS
) && (soright
!= IP_NULL
))
512 ipc_notify_port_deleted(soright
, name
);
518 * Routine: ipc_object_copyin_from_kernel
520 * Copyin a naked capability from the kernel.
522 * MACH_MSG_TYPE_MOVE_RECEIVE
523 * The receiver must be ipc_space_kernel
524 * or the receive right must already be in limbo.
525 * Consumes the naked receive right.
526 * MACH_MSG_TYPE_COPY_SEND
527 * A naked send right must be supplied.
528 * The port gains a reference, and a send right
529 * if the port is still active.
530 * MACH_MSG_TYPE_MAKE_SEND
531 * The receiver must be ipc_space_kernel.
532 * The port gains a reference and a send right.
533 * MACH_MSG_TYPE_MOVE_SEND
534 * Consumes a naked send right.
535 * MACH_MSG_TYPE_MAKE_SEND_ONCE
536 * The port gains a reference and a send-once right.
537 * Receiver also be the caller of device subsystem,
539 * MACH_MSG_TYPE_MOVE_SEND_ONCE
540 * Consumes a naked send-once right.
546 ipc_object_copyin_from_kernel(
548 mach_msg_type_name_t msgt_name
)
550 assert(IO_VALID(object
));
553 case MACH_MSG_TYPE_MOVE_RECEIVE
: {
554 ipc_port_t port
= (ipc_port_t
) object
;
557 assert(ip_active(port
));
558 if (port
->ip_destination
!= IP_NULL
) {
559 assert(port
->ip_receiver
== ipc_space_kernel
);
561 /* relevant part of ipc_port_clear_receiver */
562 ipc_port_set_mscount(port
, 0);
564 port
->ip_receiver_name
= MACH_PORT_NULL
;
565 port
->ip_destination
= IP_NULL
;
571 case MACH_MSG_TYPE_COPY_SEND
: {
572 ipc_port_t port
= (ipc_port_t
) object
;
575 if (ip_active(port
)) {
576 assert(port
->ip_srights
> 0);
584 case MACH_MSG_TYPE_MAKE_SEND
: {
585 ipc_port_t port
= (ipc_port_t
) object
;
588 assert(ip_active(port
));
589 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
590 assert(port
->ip_receiver
== ipc_space_kernel
);
599 case MACH_MSG_TYPE_MOVE_SEND
: {
600 /* move naked send right into the message */
601 assert(((ipc_port_t
)object
)->ip_srights
);
605 case MACH_MSG_TYPE_MAKE_SEND_ONCE
: {
606 ipc_port_t port
= (ipc_port_t
) object
;
609 assert(ip_active(port
));
610 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
618 case MACH_MSG_TYPE_MOVE_SEND_ONCE
: {
619 /* move naked send-once right into the message */
620 assert(((ipc_port_t
)object
)->ip_sorights
);
625 panic("ipc_object_copyin_from_kernel: strange rights");
630 * Routine: ipc_object_destroy
632 * Destroys a naked capability.
633 * Consumes a ref for the object.
635 * A receive right should be in limbo or in transit.
643 mach_msg_type_name_t msgt_name
)
645 assert(IO_VALID(object
));
646 assert(io_otype(object
) == IOT_PORT
);
649 case MACH_MSG_TYPE_PORT_SEND
:
650 ipc_port_release_send((ipc_port_t
) object
);
653 case MACH_MSG_TYPE_PORT_SEND_ONCE
:
654 ipc_notify_send_once((ipc_port_t
) object
);
657 case MACH_MSG_TYPE_PORT_RECEIVE
:
658 ipc_port_release_receive((ipc_port_t
) object
);
662 panic("ipc_object_destroy: strange rights");
667 * Routine: ipc_object_copyout
669 * Copyout a capability, placing it into a space.
670 * If successful, consumes a ref for the object.
674 * KERN_SUCCESS Copied out object, consumed ref.
675 * KERN_INVALID_TASK The space is dead.
676 * KERN_INVALID_CAPABILITY The object is dead.
677 * KERN_NO_SPACE No room in space for another right.
678 * KERN_RESOURCE_SHORTAGE No memory available.
679 * KERN_UREFS_OVERFLOW Urefs limit exceeded
680 * and overflow wasn't specified.
687 mach_msg_type_name_t msgt_name
,
689 mach_port_name_t
*namep
)
691 mach_port_name_t name
;
695 assert(IO_VALID(object
));
696 assert(io_otype(object
) == IOT_PORT
);
698 is_write_lock(space
);
701 if (!space
->is_active
) {
702 is_write_unlock(space
);
703 return KERN_INVALID_TASK
;
706 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
707 ipc_right_reverse(space
, object
, &name
, &entry
)) {
708 /* object is locked and active */
710 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
714 name
= (mach_port_name_t
)object
;
715 kr
= ipc_entry_get(space
, &name
, &entry
);
716 if (kr
!= KERN_SUCCESS
) {
717 /* unlocks/locks space, so must start again */
719 kr
= ipc_entry_grow_table(space
, ITS_SIZE_NONE
);
720 if (kr
!= KERN_SUCCESS
)
721 return kr
; /* space is unlocked */
726 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
727 assert(entry
->ie_object
== IO_NULL
);
730 if (!io_active(object
)) {
732 ipc_entry_dealloc(space
, name
, entry
);
733 is_write_unlock(space
);
734 return KERN_INVALID_CAPABILITY
;
737 entry
->ie_object
= object
;
741 /* space is write-locked and active, object is locked and active */
743 kr
= ipc_right_copyout(space
, name
, entry
,
744 msgt_name
, overflow
, object
);
745 /* object is unlocked */
746 is_write_unlock(space
);
748 if (kr
== KERN_SUCCESS
)
754 * Routine: ipc_object_copyout_name
756 * Copyout a capability, placing it into a space.
757 * The specified name is used for the capability.
758 * If successful, consumes a ref for the object.
762 * KERN_SUCCESS Copied out object, consumed ref.
763 * KERN_INVALID_TASK The space is dead.
764 * KERN_INVALID_CAPABILITY The object is dead.
765 * KERN_RESOURCE_SHORTAGE No memory available.
766 * KERN_UREFS_OVERFLOW Urefs limit exceeded
767 * and overflow wasn't specified.
768 * KERN_RIGHT_EXISTS Space has rights under another name.
769 * KERN_NAME_EXISTS Name is already used.
773 ipc_object_copyout_name(
776 mach_msg_type_name_t msgt_name
,
778 mach_port_name_t name
)
780 mach_port_name_t oname
;
785 assert(IO_VALID(object
));
786 assert(io_otype(object
) == IOT_PORT
);
788 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
789 if (kr
!= KERN_SUCCESS
)
791 /* space is write-locked and active */
793 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
794 ipc_right_reverse(space
, object
, &oname
, &oentry
)) {
795 /* object is locked and active */
800 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
801 ipc_entry_dealloc(space
, name
, entry
);
803 is_write_unlock(space
);
804 return KERN_RIGHT_EXISTS
;
807 assert(entry
== oentry
);
808 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
810 if (ipc_right_inuse(space
, name
, entry
))
811 return KERN_NAME_EXISTS
;
813 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
814 assert(entry
->ie_object
== IO_NULL
);
817 if (!io_active(object
)) {
819 ipc_entry_dealloc(space
, name
, entry
);
820 is_write_unlock(space
);
821 return KERN_INVALID_CAPABILITY
;
824 entry
->ie_object
= object
;
827 /* space is write-locked and active, object is locked and active */
829 kr
= ipc_right_copyout(space
, name
, entry
,
830 msgt_name
, overflow
, object
);
831 /* object is unlocked */
832 is_write_unlock(space
);
837 * Routine: ipc_object_copyout_dest
839 * Translates/consumes the destination right of a message.
840 * This is unlike normal copyout because the right is consumed
841 * in a funny way instead of being given to the receiving space.
842 * The receiver gets his name for the port, if he has receive
843 * rights, otherwise MACH_PORT_NULL.
845 * The object is locked and active. Nothing else locked.
846 * The object is unlocked and loses a reference.
850 ipc_object_copyout_dest(
853 mach_msg_type_name_t msgt_name
,
854 mach_port_name_t
*namep
)
856 mach_port_name_t name
;
858 assert(IO_VALID(object
));
859 assert(io_active(object
));
864 * If the space is the receiver/owner of the object,
865 * then we quietly consume the right and return
866 * the space's name for the object. Otherwise
867 * we destroy the right and return MACH_PORT_NULL.
871 case MACH_MSG_TYPE_PORT_SEND
: {
872 ipc_port_t port
= (ipc_port_t
) object
;
873 ipc_port_t nsrequest
= IP_NULL
;
874 mach_port_mscount_t mscount
;
876 if (port
->ip_receiver
== space
)
877 name
= port
->ip_receiver_name
;
879 name
= MACH_PORT_NULL
;
881 assert(port
->ip_srights
> 0);
882 if (--port
->ip_srights
== 0 &&
883 port
->ip_nsrequest
!= IP_NULL
) {
884 nsrequest
= port
->ip_nsrequest
;
885 port
->ip_nsrequest
= IP_NULL
;
886 mscount
= port
->ip_mscount
;
888 ipc_notify_no_senders(nsrequest
, mscount
);
894 case MACH_MSG_TYPE_PORT_SEND_ONCE
: {
895 ipc_port_t port
= (ipc_port_t
) object
;
897 assert(port
->ip_sorights
> 0);
899 if (port
->ip_receiver
== space
) {
900 /* quietly consume the send-once right */
903 name
= port
->ip_receiver_name
;
907 * A very bizarre case. The message
908 * was received, but before this copyout
909 * happened the space lost receive rights.
910 * We can't quietly consume the soright
911 * out from underneath some other task,
912 * so generate a send-once notification.
915 ip_reference(port
); /* restore ref */
918 ipc_notify_send_once(port
);
919 name
= MACH_PORT_NULL
;
926 panic("ipc_object_copyout_dest: strange rights");
927 name
= MACH_PORT_DEAD
;
934 * Routine: ipc_object_rename
936 * Rename an entry in a space.
940 * KERN_SUCCESS Renamed the entry.
941 * KERN_INVALID_TASK The space was dead.
942 * KERN_INVALID_NAME oname didn't denote an entry.
943 * KERN_NAME_EXISTS nname already denoted an entry.
944 * KERN_RESOURCE_SHORTAGE Couldn't allocate new entry.
950 mach_port_name_t oname
,
951 mach_port_name_t nname
)
953 ipc_entry_t oentry
, nentry
;
956 kr
= ipc_entry_alloc_name(space
, nname
, &nentry
);
957 if (kr
!= KERN_SUCCESS
)
960 /* space is write-locked and active */
962 if (ipc_right_inuse(space
, nname
, nentry
)) {
963 /* space is unlocked */
964 return KERN_NAME_EXISTS
;
967 /* don't let ipc_entry_lookup see the uninitialized new entry */
969 if ((oname
== nname
) ||
970 ((oentry
= ipc_entry_lookup(space
, oname
)) == IE_NULL
)) {
971 ipc_entry_dealloc(space
, nname
, nentry
);
972 is_write_unlock(space
);
973 return KERN_INVALID_NAME
;
976 kr
= ipc_right_rename(space
, oname
, oentry
, nname
, nentry
);
977 /* space is unlocked */
983 * Check whether the object is a port if so, free it. But
984 * keep track of that fact.
993 if (otype
== IOT_PORT
) {
994 port
= (ipc_port_t
) object
;
996 ipc_port_track_dealloc(port
);
997 #endif /* MACH_ASSERT */
999 zfree(ipc_object_zones
[otype
], object
);
1001 #endif /* MACH_ASSERT */
1003 #include <mach_kdb.h>
1006 #include <ddb/db_output.h>
1007 #include <kern/ipc_kobject.h>
1009 #define printf kdbprintf
1012 * Routine: ipc_object_print
1014 * Pretty-print an object for kdb.
1017 const char *ikot_print_array
[IKOT_MAX_TYPE
] = {
1028 "(DEVICE) ", /* 10 */
1038 "(ACTIVATION) ", /* 20 */
1044 "(CLOCK_CTRL) ", /* 26 */
1045 "(IOKIT_SPARE) ", /* 27 */
1046 "(NAMED_MEM_ENTRY) ", /* 28 */
1048 "(IOKIT_OBJECT) ", /* 30 */
1050 /* << new entries here */
1051 "(UNKNOWN) " /* magic catchall */
1053 /* Please keep in sync with kern/ipc_kobject.h */
1057 ipc_object_t object
)
1061 iprintf("%s", io_active(object
) ? "active" : "dead");
1062 printf(", refs=%d", object
->io_references
);
1063 printf(", otype=%d", io_otype(object
));
1064 kotype
= io_kotype(object
);
1065 if (kotype
>= 0 && kotype
< IKOT_MAX_TYPE
)
1066 printf(", kotype=%d %s\n", io_kotype(object
),
1067 ikot_print_array
[kotype
]);
1069 printf(", kotype=0x%x %s\n", io_kotype(object
),
1070 ikot_print_array
[IKOT_UNKNOWN
]);
1073 #endif /* MACH_KDB */