2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
53 * File: ipc/ipc_object.c
57 * Functions to manipulate IPC objects.
62 #include <mach/mach_types.h>
63 #include <mach/boolean.h>
64 #include <mach/kern_return.h>
65 #include <mach/port.h>
66 #include <mach/message.h>
68 #include <kern/kern_types.h>
69 #include <kern/misc_protos.h>
71 #include <ipc/ipc_types.h>
73 #include <ipc/ipc_space.h>
74 #include <ipc/ipc_entry.h>
75 #include <ipc/ipc_object.h>
76 #include <ipc/ipc_hash.h>
77 #include <ipc/ipc_right.h>
78 #include <ipc/ipc_notify.h>
79 #include <ipc/ipc_pset.h>
81 zone_t ipc_object_zones
[IOT_NUMBER
];
84 * Routine: ipc_object_reference
86 * Take a reference to an object.
94 assert(object
->io_references
> 0);
100 * Routine: ipc_object_release
102 * Release a reference to an object.
110 assert(object
->io_references
> 0);
112 io_check_unlock(object
);
116 * Routine: ipc_object_translate
118 * Look up an object in a space.
120 * Nothing locked before. If successful, the object
121 * is returned locked. The caller doesn't get a ref.
123 * KERN_SUCCESS Object returned locked.
124 * KERN_INVALID_TASK The space is dead.
125 * KERN_INVALID_NAME The name doesn't denote a right.
126 * KERN_INVALID_RIGHT Name doesn't denote the correct right.
130 ipc_object_translate(
132 mach_port_name_t name
,
133 mach_port_right_t right
,
134 ipc_object_t
*objectp
)
140 kr
= ipc_right_lookup_read(space
, name
, &entry
);
141 if (kr
!= KERN_SUCCESS
)
143 /* space is read-locked and active */
145 if ((entry
->ie_bits
& MACH_PORT_TYPE(right
)) == MACH_PORT_TYPE_NONE
) {
146 is_read_unlock(space
);
147 return KERN_INVALID_RIGHT
;
150 object
= entry
->ie_object
;
151 assert(object
!= IO_NULL
);
154 is_read_unlock(space
);
161 * Routine: ipc_object_translate_two
163 * Look up two objects in a space.
165 * Nothing locked before. If successful, the objects
166 * are returned locked. The caller doesn't get a ref.
168 * KERN_SUCCESS Objects returned locked.
169 * KERN_INVALID_TASK The space is dead.
170 * KERN_INVALID_NAME A name doesn't denote a right.
171 * KERN_INVALID_RIGHT A name doesn't denote the correct right.
175 ipc_object_translate_two(
177 mach_port_name_t name1
,
178 mach_port_right_t right1
,
179 ipc_object_t
*objectp1
,
180 mach_port_name_t name2
,
181 mach_port_right_t right2
,
182 ipc_object_t
*objectp2
)
189 kr
= ipc_right_lookup_two_read(space
, name1
, &entry1
, name2
, &entry2
);
190 if (kr
!= KERN_SUCCESS
)
192 /* space is read-locked and active */
194 if ((entry1
->ie_bits
& MACH_PORT_TYPE(right1
)) == MACH_PORT_TYPE_NONE
) {
195 is_read_unlock(space
);
196 return KERN_INVALID_RIGHT
;
199 if ((entry2
->ie_bits
& MACH_PORT_TYPE(right2
)) == MACH_PORT_TYPE_NONE
) {
200 is_read_unlock(space
);
201 return KERN_INVALID_RIGHT
;
204 object
= entry1
->ie_object
;
205 assert(object
!= IO_NULL
);
209 object
= entry2
->ie_object
;
210 assert(object
!= IO_NULL
);
214 is_read_unlock(space
);
219 * Routine: ipc_object_alloc_dead
221 * Allocate a dead-name entry.
225 * KERN_SUCCESS The dead name is allocated.
226 * KERN_INVALID_TASK The space is dead.
227 * KERN_NO_SPACE No room for an entry in the space.
228 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
232 ipc_object_alloc_dead(
234 mach_port_name_t
*namep
)
239 kr
= ipc_entry_alloc(space
, namep
, &entry
);
240 if (kr
!= KERN_SUCCESS
)
242 /* space is write-locked */
244 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
246 assert(entry
->ie_object
== IO_NULL
);
247 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
249 is_write_unlock(space
);
254 * Routine: ipc_object_alloc_dead_name
256 * Allocate a dead-name entry, with a specific name.
260 * KERN_SUCCESS The dead name is allocated.
261 * KERN_INVALID_TASK The space is dead.
262 * KERN_NAME_EXISTS The name already denotes a right.
263 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
267 ipc_object_alloc_dead_name(
269 mach_port_name_t name
)
274 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
275 if (kr
!= KERN_SUCCESS
)
277 /* space is write-locked */
279 if (ipc_right_inuse(space
, name
, entry
))
280 return KERN_NAME_EXISTS
;
282 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
284 assert(entry
->ie_object
== IO_NULL
);
285 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
287 is_write_unlock(space
);
292 * Routine: ipc_object_alloc
294 * Allocate an object.
296 * Nothing locked. If successful, the object is returned locked.
297 * The caller doesn't get a reference for the object.
299 * KERN_SUCCESS The object is allocated.
300 * KERN_INVALID_TASK The space is dead.
301 * KERN_NO_SPACE No room for an entry in the space.
302 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
308 ipc_object_type_t otype
,
309 mach_port_type_t type
,
310 mach_port_urefs_t urefs
,
311 mach_port_name_t
*namep
,
312 ipc_object_t
*objectp
)
318 assert(otype
< IOT_NUMBER
);
319 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
320 assert(type
!= MACH_PORT_TYPE_NONE
);
321 assert(urefs
<= MACH_PORT_UREFS_MAX
);
323 object
= io_alloc(otype
);
324 if (object
== IO_NULL
)
325 return KERN_RESOURCE_SHORTAGE
;
327 if (otype
== IOT_PORT
) {
328 ipc_port_t port
= (ipc_port_t
)object
;
330 bzero((char *)port
, sizeof(*port
));
331 } else if (otype
== IOT_PORT_SET
) {
332 ipc_pset_t pset
= (ipc_pset_t
)object
;
334 bzero((char *)pset
, sizeof(*pset
));
337 io_lock_init(object
);
338 *namep
= (mach_port_name_t
)object
;
339 kr
= ipc_entry_alloc(space
, namep
, &entry
);
340 if (kr
!= KERN_SUCCESS
) {
341 io_free(otype
, object
);
344 /* space is write-locked */
346 entry
->ie_bits
|= type
| urefs
;
347 entry
->ie_object
= object
;
350 is_write_unlock(space
);
352 object
->io_references
= 1; /* for entry, not caller */
353 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
360 * Routine: ipc_object_alloc_name
362 * Allocate an object, with a specific name.
364 * Nothing locked. If successful, the object is returned locked.
365 * The caller doesn't get a reference for the object.
367 * KERN_SUCCESS The object is allocated.
368 * KERN_INVALID_TASK The space is dead.
369 * KERN_NAME_EXISTS The name already denotes a right.
370 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
374 ipc_object_alloc_name(
376 ipc_object_type_t otype
,
377 mach_port_type_t type
,
378 mach_port_urefs_t urefs
,
379 mach_port_name_t name
,
380 ipc_object_t
*objectp
)
386 assert(otype
< IOT_NUMBER
);
387 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
388 assert(type
!= MACH_PORT_TYPE_NONE
);
389 assert(urefs
<= MACH_PORT_UREFS_MAX
);
391 object
= io_alloc(otype
);
392 if (object
== IO_NULL
)
393 return KERN_RESOURCE_SHORTAGE
;
395 if (otype
== IOT_PORT
) {
396 ipc_port_t port
= (ipc_port_t
)object
;
398 bzero((char *)port
, sizeof(*port
));
399 } else if (otype
== IOT_PORT_SET
) {
400 ipc_pset_t pset
= (ipc_pset_t
)object
;
402 bzero((char *)pset
, sizeof(*pset
));
405 io_lock_init(object
);
406 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
407 if (kr
!= KERN_SUCCESS
) {
408 io_free(otype
, object
);
411 /* space is write-locked */
413 if (ipc_right_inuse(space
, name
, entry
)) {
414 io_free(otype
, object
);
415 return KERN_NAME_EXISTS
;
418 entry
->ie_bits
|= type
| urefs
;
419 entry
->ie_object
= object
;
422 is_write_unlock(space
);
424 object
->io_references
= 1; /* for entry, not caller */
425 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
432 * Routine: ipc_object_copyin_type
434 * Convert a send type name to a received type name.
438 ipc_object_copyin_type(
439 mach_msg_type_name_t msgt_name
)
443 case MACH_MSG_TYPE_MOVE_RECEIVE
:
444 case MACH_MSG_TYPE_COPY_RECEIVE
:
445 return MACH_MSG_TYPE_PORT_RECEIVE
;
447 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
448 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
449 return MACH_MSG_TYPE_PORT_SEND_ONCE
;
451 case MACH_MSG_TYPE_MOVE_SEND
:
452 case MACH_MSG_TYPE_MAKE_SEND
:
453 case MACH_MSG_TYPE_COPY_SEND
:
454 return MACH_MSG_TYPE_PORT_SEND
;
457 return MACH_MSG_TYPE_PORT_NONE
;
462 * Routine: ipc_object_copyin
464 * Copyin a capability from a space.
465 * If successful, the caller gets a ref
466 * for the resulting object, unless it is IO_DEAD.
470 * KERN_SUCCESS Acquired an object, possibly IO_DEAD.
471 * KERN_INVALID_TASK The space is dead.
472 * KERN_INVALID_NAME Name doesn't exist in space.
473 * KERN_INVALID_RIGHT Name doesn't denote correct right.
479 mach_port_name_t name
,
480 mach_msg_type_name_t msgt_name
,
481 ipc_object_t
*objectp
)
488 * Could first try a read lock when doing
489 * MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND,
490 * and MACH_MSG_TYPE_MAKE_SEND_ONCE.
493 kr
= ipc_right_lookup_write(space
, name
, &entry
);
494 if (kr
!= KERN_SUCCESS
)
496 /* space is write-locked and active */
498 kr
= ipc_right_copyin(space
, name
, entry
,
501 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
502 ipc_entry_dealloc(space
, name
, entry
);
503 is_write_unlock(space
);
505 if ((kr
== KERN_SUCCESS
) && (soright
!= IP_NULL
))
506 ipc_notify_port_deleted(soright
, name
);
512 * Routine: ipc_object_copyin_from_kernel
514 * Copyin a naked capability from the kernel.
516 * MACH_MSG_TYPE_MOVE_RECEIVE
517 * The receiver must be ipc_space_kernel
518 * or the receive right must already be in limbo.
519 * Consumes the naked receive right.
520 * MACH_MSG_TYPE_COPY_SEND
521 * A naked send right must be supplied.
522 * The port gains a reference, and a send right
523 * if the port is still active.
524 * MACH_MSG_TYPE_MAKE_SEND
525 * The receiver must be ipc_space_kernel.
526 * The port gains a reference and a send right.
527 * MACH_MSG_TYPE_MOVE_SEND
528 * Consumes a naked send right.
529 * MACH_MSG_TYPE_MAKE_SEND_ONCE
530 * The port gains a reference and a send-once right.
531 * Receiver also be the caller of device subsystem,
533 * MACH_MSG_TYPE_MOVE_SEND_ONCE
534 * Consumes a naked send-once right.
540 ipc_object_copyin_from_kernel(
542 mach_msg_type_name_t msgt_name
)
544 assert(IO_VALID(object
));
547 case MACH_MSG_TYPE_MOVE_RECEIVE
: {
548 ipc_port_t port
= (ipc_port_t
) object
;
551 assert(ip_active(port
));
552 if (port
->ip_destination
!= IP_NULL
) {
553 assert(port
->ip_receiver
== ipc_space_kernel
);
555 /* relevant part of ipc_port_clear_receiver */
556 ipc_port_set_mscount(port
, 0);
558 port
->ip_receiver_name
= MACH_PORT_NULL
;
559 port
->ip_destination
= IP_NULL
;
565 case MACH_MSG_TYPE_COPY_SEND
: {
566 ipc_port_t port
= (ipc_port_t
) object
;
569 if (ip_active(port
)) {
570 assert(port
->ip_srights
> 0);
578 case MACH_MSG_TYPE_MAKE_SEND
: {
579 ipc_port_t port
= (ipc_port_t
) object
;
582 assert(ip_active(port
));
583 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
584 assert(port
->ip_receiver
== ipc_space_kernel
);
593 case MACH_MSG_TYPE_MOVE_SEND
: {
594 /* move naked send right into the message */
595 assert(((ipc_port_t
)object
)->ip_srights
);
599 case MACH_MSG_TYPE_MAKE_SEND_ONCE
: {
600 ipc_port_t port
= (ipc_port_t
) object
;
603 assert(ip_active(port
));
604 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
612 case MACH_MSG_TYPE_MOVE_SEND_ONCE
: {
613 /* move naked send-once right into the message */
614 assert(((ipc_port_t
)object
)->ip_sorights
);
619 panic("ipc_object_copyin_from_kernel: strange rights");
624 * Routine: ipc_object_destroy
626 * Destroys a naked capability.
627 * Consumes a ref for the object.
629 * A receive right should be in limbo or in transit.
637 mach_msg_type_name_t msgt_name
)
639 assert(IO_VALID(object
));
640 assert(io_otype(object
) == IOT_PORT
);
643 case MACH_MSG_TYPE_PORT_SEND
:
644 ipc_port_release_send((ipc_port_t
) object
);
647 case MACH_MSG_TYPE_PORT_SEND_ONCE
:
648 ipc_notify_send_once((ipc_port_t
) object
);
651 case MACH_MSG_TYPE_PORT_RECEIVE
:
652 ipc_port_release_receive((ipc_port_t
) object
);
656 panic("ipc_object_destroy: strange rights");
661 * Routine: ipc_object_copyout
663 * Copyout a capability, placing it into a space.
664 * If successful, consumes a ref for the object.
668 * KERN_SUCCESS Copied out object, consumed ref.
669 * KERN_INVALID_TASK The space is dead.
670 * KERN_INVALID_CAPABILITY The object is dead.
671 * KERN_NO_SPACE No room in space for another right.
672 * KERN_RESOURCE_SHORTAGE No memory available.
673 * KERN_UREFS_OVERFLOW Urefs limit exceeded
674 * and overflow wasn't specified.
681 mach_msg_type_name_t msgt_name
,
683 mach_port_name_t
*namep
)
685 mach_port_name_t name
;
689 assert(IO_VALID(object
));
690 assert(io_otype(object
) == IOT_PORT
);
692 is_write_lock(space
);
695 if (!space
->is_active
) {
696 is_write_unlock(space
);
697 return KERN_INVALID_TASK
;
700 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
701 ipc_right_reverse(space
, object
, &name
, &entry
)) {
702 /* object is locked and active */
704 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
708 name
= (mach_port_name_t
)object
;
709 kr
= ipc_entry_get(space
, &name
, &entry
);
710 if (kr
!= KERN_SUCCESS
) {
711 /* unlocks/locks space, so must start again */
713 kr
= ipc_entry_grow_table(space
, ITS_SIZE_NONE
);
714 if (kr
!= KERN_SUCCESS
)
715 return kr
; /* space is unlocked */
720 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
721 assert(entry
->ie_object
== IO_NULL
);
724 if (!io_active(object
)) {
726 ipc_entry_dealloc(space
, name
, entry
);
727 is_write_unlock(space
);
728 return KERN_INVALID_CAPABILITY
;
731 entry
->ie_object
= object
;
735 /* space is write-locked and active, object is locked and active */
737 kr
= ipc_right_copyout(space
, name
, entry
,
738 msgt_name
, overflow
, object
);
739 /* object is unlocked */
740 is_write_unlock(space
);
742 if (kr
== KERN_SUCCESS
)
748 * Routine: ipc_object_copyout_name
750 * Copyout a capability, placing it into a space.
751 * The specified name is used for the capability.
752 * If successful, consumes a ref for the object.
756 * KERN_SUCCESS Copied out object, consumed ref.
757 * KERN_INVALID_TASK The space is dead.
758 * KERN_INVALID_CAPABILITY The object is dead.
759 * KERN_RESOURCE_SHORTAGE No memory available.
760 * KERN_UREFS_OVERFLOW Urefs limit exceeded
761 * and overflow wasn't specified.
762 * KERN_RIGHT_EXISTS Space has rights under another name.
763 * KERN_NAME_EXISTS Name is already used.
767 ipc_object_copyout_name(
770 mach_msg_type_name_t msgt_name
,
772 mach_port_name_t name
)
774 mach_port_name_t oname
;
779 assert(IO_VALID(object
));
780 assert(io_otype(object
) == IOT_PORT
);
782 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
783 if (kr
!= KERN_SUCCESS
)
785 /* space is write-locked and active */
787 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
788 ipc_right_reverse(space
, object
, &oname
, &oentry
)) {
789 /* object is locked and active */
794 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
795 ipc_entry_dealloc(space
, name
, entry
);
797 is_write_unlock(space
);
798 return KERN_RIGHT_EXISTS
;
801 assert(entry
== oentry
);
802 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
804 if (ipc_right_inuse(space
, name
, entry
))
805 return KERN_NAME_EXISTS
;
807 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
808 assert(entry
->ie_object
== IO_NULL
);
811 if (!io_active(object
)) {
813 ipc_entry_dealloc(space
, name
, entry
);
814 is_write_unlock(space
);
815 return KERN_INVALID_CAPABILITY
;
818 entry
->ie_object
= object
;
821 /* space is write-locked and active, object is locked and active */
823 kr
= ipc_right_copyout(space
, name
, entry
,
824 msgt_name
, overflow
, object
);
825 /* object is unlocked */
826 is_write_unlock(space
);
831 * Routine: ipc_object_copyout_dest
833 * Translates/consumes the destination right of a message.
834 * This is unlike normal copyout because the right is consumed
835 * in a funny way instead of being given to the receiving space.
836 * The receiver gets his name for the port, if he has receive
837 * rights, otherwise MACH_PORT_NULL.
839 * The object is locked and active. Nothing else locked.
840 * The object is unlocked and loses a reference.
844 ipc_object_copyout_dest(
847 mach_msg_type_name_t msgt_name
,
848 mach_port_name_t
*namep
)
850 mach_port_name_t name
;
852 assert(IO_VALID(object
));
853 assert(io_active(object
));
858 * If the space is the receiver/owner of the object,
859 * then we quietly consume the right and return
860 * the space's name for the object. Otherwise
861 * we destroy the right and return MACH_PORT_NULL.
865 case MACH_MSG_TYPE_PORT_SEND
: {
866 ipc_port_t port
= (ipc_port_t
) object
;
867 ipc_port_t nsrequest
= IP_NULL
;
868 mach_port_mscount_t mscount
;
870 if (port
->ip_receiver
== space
)
871 name
= port
->ip_receiver_name
;
873 name
= MACH_PORT_NULL
;
875 assert(port
->ip_srights
> 0);
876 if (--port
->ip_srights
== 0 &&
877 port
->ip_nsrequest
!= IP_NULL
) {
878 nsrequest
= port
->ip_nsrequest
;
879 port
->ip_nsrequest
= IP_NULL
;
880 mscount
= port
->ip_mscount
;
882 ipc_notify_no_senders(nsrequest
, mscount
);
888 case MACH_MSG_TYPE_PORT_SEND_ONCE
: {
889 ipc_port_t port
= (ipc_port_t
) object
;
891 assert(port
->ip_sorights
> 0);
893 if (port
->ip_receiver
== space
) {
894 /* quietly consume the send-once right */
897 name
= port
->ip_receiver_name
;
901 * A very bizarre case. The message
902 * was received, but before this copyout
903 * happened the space lost receive rights.
904 * We can't quietly consume the soright
905 * out from underneath some other task,
906 * so generate a send-once notification.
909 ip_reference(port
); /* restore ref */
912 ipc_notify_send_once(port
);
913 name
= MACH_PORT_NULL
;
920 panic("ipc_object_copyout_dest: strange rights");
921 name
= MACH_PORT_DEAD
;
928 * Routine: ipc_object_rename
930 * Rename an entry in a space.
934 * KERN_SUCCESS Renamed the entry.
935 * KERN_INVALID_TASK The space was dead.
936 * KERN_INVALID_NAME oname didn't denote an entry.
937 * KERN_NAME_EXISTS nname already denoted an entry.
938 * KERN_RESOURCE_SHORTAGE Couldn't allocate new entry.
944 mach_port_name_t oname
,
945 mach_port_name_t nname
)
947 ipc_entry_t oentry
, nentry
;
950 kr
= ipc_entry_alloc_name(space
, nname
, &nentry
);
951 if (kr
!= KERN_SUCCESS
)
954 /* space is write-locked and active */
956 if (ipc_right_inuse(space
, nname
, nentry
)) {
957 /* space is unlocked */
958 return KERN_NAME_EXISTS
;
961 /* don't let ipc_entry_lookup see the uninitialized new entry */
963 if ((oname
== nname
) ||
964 ((oentry
= ipc_entry_lookup(space
, oname
)) == IE_NULL
)) {
965 ipc_entry_dealloc(space
, nname
, nentry
);
966 is_write_unlock(space
);
967 return KERN_INVALID_NAME
;
970 kr
= ipc_right_rename(space
, oname
, oentry
, nname
, nentry
);
971 /* space is unlocked */
977 * Check whether the object is a port if so, free it. But
978 * keep track of that fact.
987 if (otype
== IOT_PORT
) {
988 port
= (ipc_port_t
) object
;
990 ipc_port_track_dealloc(port
);
991 #endif /* MACH_ASSERT */
993 zfree(ipc_object_zones
[otype
], object
);
995 #endif /* MACH_ASSERT */
997 #include <mach_kdb.h>
1000 #include <ddb/db_output.h>
1001 #include <kern/ipc_kobject.h>
1003 #define printf kdbprintf
1006 * Routine: ipc_object_print
1008 * Pretty-print an object for kdb.
1011 const char *ikot_print_array
[IKOT_MAX_TYPE
] = {
1022 "(DEVICE) ", /* 10 */
1032 "(ACTIVATION) ", /* 20 */
1038 "(CLOCK_CTRL) ", /* 26 */
1039 "(IOKIT_SPARE) ", /* 27 */
1040 "(NAMED_MEM_ENTRY) ", /* 28 */
1042 "(IOKIT_OBJECT) ", /* 30 */
1044 /* << new entries here */
1045 "(UNKNOWN) " /* magic catchall */
1047 /* Please keep in sync with kern/ipc_kobject.h */
1051 ipc_object_t object
)
1055 iprintf("%s", io_active(object
) ? "active" : "dead");
1056 printf(", refs=%d", object
->io_references
);
1057 printf(", otype=%d", io_otype(object
));
1058 kotype
= io_kotype(object
);
1059 if (kotype
>= 0 && kotype
< IKOT_MAX_TYPE
)
1060 printf(", kotype=%d %s\n", io_kotype(object
),
1061 ikot_print_array
[kotype
]);
1063 printf(", kotype=0x%x %s\n", io_kotype(object
),
1064 ikot_print_array
[IKOT_UNKNOWN
]);
1067 #endif /* MACH_KDB */