2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 * Mach Operating System
28 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie Mellon
49 * the rights to redistribute these changes.
54 * File: ipc/ipc_object.c
58 * Functions to manipulate IPC objects.
63 #include <mach/mach_types.h>
64 #include <mach/boolean.h>
65 #include <mach/kern_return.h>
66 #include <mach/port.h>
67 #include <mach/message.h>
69 #include <kern/kern_types.h>
70 #include <kern/misc_protos.h>
72 #include <ipc/ipc_types.h>
74 #include <ipc/ipc_space.h>
75 #include <ipc/ipc_entry.h>
76 #include <ipc/ipc_object.h>
77 #include <ipc/ipc_hash.h>
78 #include <ipc/ipc_right.h>
79 #include <ipc/ipc_notify.h>
80 #include <ipc/ipc_pset.h>
82 zone_t ipc_object_zones
[IOT_NUMBER
];
85 * Routine: ipc_object_reference
87 * Take a reference to an object.
95 assert(object
->io_references
> 0);
101 * Routine: ipc_object_release
103 * Release a reference to an object.
111 assert(object
->io_references
> 0);
113 io_check_unlock(object
);
117 * Routine: ipc_object_translate
119 * Look up an object in a space.
121 * Nothing locked before. If successful, the object
122 * is returned locked. The caller doesn't get a ref.
124 * KERN_SUCCESS Object returned locked.
125 * KERN_INVALID_TASK The space is dead.
126 * KERN_INVALID_NAME The name doesn't denote a right.
127 * KERN_INVALID_RIGHT Name doesn't denote the correct right.
131 ipc_object_translate(
133 mach_port_name_t name
,
134 mach_port_right_t right
,
135 ipc_object_t
*objectp
)
141 kr
= ipc_right_lookup_read(space
, name
, &entry
);
142 if (kr
!= KERN_SUCCESS
)
144 /* space is read-locked and active */
146 if ((entry
->ie_bits
& MACH_PORT_TYPE(right
)) == MACH_PORT_TYPE_NONE
) {
147 is_read_unlock(space
);
148 return KERN_INVALID_RIGHT
;
151 object
= entry
->ie_object
;
152 assert(object
!= IO_NULL
);
155 is_read_unlock(space
);
162 * Routine: ipc_object_translate_two
164 * Look up two objects in a space.
166 * Nothing locked before. If successful, the objects
167 * are returned locked. The caller doesn't get a ref.
169 * KERN_SUCCESS Objects returned locked.
170 * KERN_INVALID_TASK The space is dead.
171 * KERN_INVALID_NAME A name doesn't denote a right.
172 * KERN_INVALID_RIGHT A name doesn't denote the correct right.
176 ipc_object_translate_two(
178 mach_port_name_t name1
,
179 mach_port_right_t right1
,
180 ipc_object_t
*objectp1
,
181 mach_port_name_t name2
,
182 mach_port_right_t right2
,
183 ipc_object_t
*objectp2
)
190 kr
= ipc_right_lookup_two_read(space
, name1
, &entry1
, name2
, &entry2
);
191 if (kr
!= KERN_SUCCESS
)
193 /* space is read-locked and active */
195 if ((entry1
->ie_bits
& MACH_PORT_TYPE(right1
)) == MACH_PORT_TYPE_NONE
) {
196 is_read_unlock(space
);
197 return KERN_INVALID_RIGHT
;
200 if ((entry2
->ie_bits
& MACH_PORT_TYPE(right2
)) == MACH_PORT_TYPE_NONE
) {
201 is_read_unlock(space
);
202 return KERN_INVALID_RIGHT
;
205 object
= entry1
->ie_object
;
206 assert(object
!= IO_NULL
);
210 object
= entry2
->ie_object
;
211 assert(object
!= IO_NULL
);
215 is_read_unlock(space
);
220 * Routine: ipc_object_alloc_dead
222 * Allocate a dead-name entry.
226 * KERN_SUCCESS The dead name is allocated.
227 * KERN_INVALID_TASK The space is dead.
228 * KERN_NO_SPACE No room for an entry in the space.
229 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
233 ipc_object_alloc_dead(
235 mach_port_name_t
*namep
)
240 kr
= ipc_entry_alloc(space
, namep
, &entry
);
241 if (kr
!= KERN_SUCCESS
)
243 /* space is write-locked */
245 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
247 assert(entry
->ie_object
== IO_NULL
);
248 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
250 is_write_unlock(space
);
255 * Routine: ipc_object_alloc_dead_name
257 * Allocate a dead-name entry, with a specific name.
261 * KERN_SUCCESS The dead name is allocated.
262 * KERN_INVALID_TASK The space is dead.
263 * KERN_NAME_EXISTS The name already denotes a right.
264 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
268 ipc_object_alloc_dead_name(
270 mach_port_name_t name
)
275 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
276 if (kr
!= KERN_SUCCESS
)
278 /* space is write-locked */
280 if (ipc_right_inuse(space
, name
, entry
))
281 return KERN_NAME_EXISTS
;
283 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
285 assert(entry
->ie_object
== IO_NULL
);
286 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
288 is_write_unlock(space
);
293 * Routine: ipc_object_alloc
295 * Allocate an object.
297 * Nothing locked. If successful, the object is returned locked.
298 * The caller doesn't get a reference for the object.
300 * KERN_SUCCESS The object is allocated.
301 * KERN_INVALID_TASK The space is dead.
302 * KERN_NO_SPACE No room for an entry in the space.
303 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
309 ipc_object_type_t otype
,
310 mach_port_type_t type
,
311 mach_port_urefs_t urefs
,
312 mach_port_name_t
*namep
,
313 ipc_object_t
*objectp
)
319 assert(otype
< IOT_NUMBER
);
320 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
321 assert(type
!= MACH_PORT_TYPE_NONE
);
322 assert(urefs
<= MACH_PORT_UREFS_MAX
);
324 object
= io_alloc(otype
);
325 if (object
== IO_NULL
)
326 return KERN_RESOURCE_SHORTAGE
;
328 if (otype
== IOT_PORT
) {
329 ipc_port_t port
= (ipc_port_t
)object
;
331 bzero((char *)port
, sizeof(*port
));
332 } else if (otype
== IOT_PORT_SET
) {
333 ipc_pset_t pset
= (ipc_pset_t
)object
;
335 bzero((char *)pset
, sizeof(*pset
));
338 io_lock_init(object
);
339 *namep
= (mach_port_name_t
)object
;
340 kr
= ipc_entry_alloc(space
, namep
, &entry
);
341 if (kr
!= KERN_SUCCESS
) {
342 io_free(otype
, object
);
345 /* space is write-locked */
347 entry
->ie_bits
|= type
| urefs
;
348 entry
->ie_object
= object
;
351 is_write_unlock(space
);
353 object
->io_references
= 1; /* for entry, not caller */
354 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
361 * Routine: ipc_object_alloc_name
363 * Allocate an object, with a specific name.
365 * Nothing locked. If successful, the object is returned locked.
366 * The caller doesn't get a reference for the object.
368 * KERN_SUCCESS The object is allocated.
369 * KERN_INVALID_TASK The space is dead.
370 * KERN_NAME_EXISTS The name already denotes a right.
371 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
375 ipc_object_alloc_name(
377 ipc_object_type_t otype
,
378 mach_port_type_t type
,
379 mach_port_urefs_t urefs
,
380 mach_port_name_t name
,
381 ipc_object_t
*objectp
)
387 assert(otype
< IOT_NUMBER
);
388 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
389 assert(type
!= MACH_PORT_TYPE_NONE
);
390 assert(urefs
<= MACH_PORT_UREFS_MAX
);
392 object
= io_alloc(otype
);
393 if (object
== IO_NULL
)
394 return KERN_RESOURCE_SHORTAGE
;
396 if (otype
== IOT_PORT
) {
397 ipc_port_t port
= (ipc_port_t
)object
;
399 bzero((char *)port
, sizeof(*port
));
400 } else if (otype
== IOT_PORT_SET
) {
401 ipc_pset_t pset
= (ipc_pset_t
)object
;
403 bzero((char *)pset
, sizeof(*pset
));
406 io_lock_init(object
);
407 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
408 if (kr
!= KERN_SUCCESS
) {
409 io_free(otype
, object
);
412 /* space is write-locked */
414 if (ipc_right_inuse(space
, name
, entry
)) {
415 io_free(otype
, object
);
416 return KERN_NAME_EXISTS
;
419 entry
->ie_bits
|= type
| urefs
;
420 entry
->ie_object
= object
;
423 is_write_unlock(space
);
425 object
->io_references
= 1; /* for entry, not caller */
426 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
433 * Routine: ipc_object_copyin_type
435 * Convert a send type name to a received type name.
439 ipc_object_copyin_type(
440 mach_msg_type_name_t msgt_name
)
444 case MACH_MSG_TYPE_MOVE_RECEIVE
:
445 case MACH_MSG_TYPE_COPY_RECEIVE
:
446 return MACH_MSG_TYPE_PORT_RECEIVE
;
448 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
449 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
450 return MACH_MSG_TYPE_PORT_SEND_ONCE
;
452 case MACH_MSG_TYPE_MOVE_SEND
:
453 case MACH_MSG_TYPE_MAKE_SEND
:
454 case MACH_MSG_TYPE_COPY_SEND
:
455 return MACH_MSG_TYPE_PORT_SEND
;
458 return MACH_MSG_TYPE_PORT_NONE
;
463 * Routine: ipc_object_copyin
465 * Copyin a capability from a space.
466 * If successful, the caller gets a ref
467 * for the resulting object, unless it is IO_DEAD.
471 * KERN_SUCCESS Acquired an object, possibly IO_DEAD.
472 * KERN_INVALID_TASK The space is dead.
473 * KERN_INVALID_NAME Name doesn't exist in space.
474 * KERN_INVALID_RIGHT Name doesn't denote correct right.
480 mach_port_name_t name
,
481 mach_msg_type_name_t msgt_name
,
482 ipc_object_t
*objectp
)
489 * Could first try a read lock when doing
490 * MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND,
491 * and MACH_MSG_TYPE_MAKE_SEND_ONCE.
494 kr
= ipc_right_lookup_write(space
, name
, &entry
);
495 if (kr
!= KERN_SUCCESS
)
497 /* space is write-locked and active */
499 kr
= ipc_right_copyin(space
, name
, entry
,
502 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
503 ipc_entry_dealloc(space
, name
, entry
);
504 is_write_unlock(space
);
506 if ((kr
== KERN_SUCCESS
) && (soright
!= IP_NULL
))
507 ipc_notify_port_deleted(soright
, name
);
513 * Routine: ipc_object_copyin_from_kernel
515 * Copyin a naked capability from the kernel.
517 * MACH_MSG_TYPE_MOVE_RECEIVE
518 * The receiver must be ipc_space_kernel
519 * or the receive right must already be in limbo.
520 * Consumes the naked receive right.
521 * MACH_MSG_TYPE_COPY_SEND
522 * A naked send right must be supplied.
523 * The port gains a reference, and a send right
524 * if the port is still active.
525 * MACH_MSG_TYPE_MAKE_SEND
526 * The receiver must be ipc_space_kernel.
527 * The port gains a reference and a send right.
528 * MACH_MSG_TYPE_MOVE_SEND
529 * Consumes a naked send right.
530 * MACH_MSG_TYPE_MAKE_SEND_ONCE
531 * The port gains a reference and a send-once right.
532 * Receiver also be the caller of device subsystem,
534 * MACH_MSG_TYPE_MOVE_SEND_ONCE
535 * Consumes a naked send-once right.
541 ipc_object_copyin_from_kernel(
543 mach_msg_type_name_t msgt_name
)
545 assert(IO_VALID(object
));
548 case MACH_MSG_TYPE_MOVE_RECEIVE
: {
549 ipc_port_t port
= (ipc_port_t
) object
;
552 assert(ip_active(port
));
553 if (port
->ip_destination
!= IP_NULL
) {
554 assert(port
->ip_receiver
== ipc_space_kernel
);
556 /* relevant part of ipc_port_clear_receiver */
557 ipc_port_set_mscount(port
, 0);
559 port
->ip_receiver_name
= MACH_PORT_NULL
;
560 port
->ip_destination
= IP_NULL
;
566 case MACH_MSG_TYPE_COPY_SEND
: {
567 ipc_port_t port
= (ipc_port_t
) object
;
570 if (ip_active(port
)) {
571 assert(port
->ip_srights
> 0);
579 case MACH_MSG_TYPE_MAKE_SEND
: {
580 ipc_port_t port
= (ipc_port_t
) object
;
583 assert(ip_active(port
));
584 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
585 assert(port
->ip_receiver
== ipc_space_kernel
);
594 case MACH_MSG_TYPE_MOVE_SEND
: {
595 /* move naked send right into the message */
596 assert(((ipc_port_t
)object
)->ip_srights
);
600 case MACH_MSG_TYPE_MAKE_SEND_ONCE
: {
601 ipc_port_t port
= (ipc_port_t
) object
;
604 assert(ip_active(port
));
605 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
613 case MACH_MSG_TYPE_MOVE_SEND_ONCE
: {
614 /* move naked send-once right into the message */
615 assert(((ipc_port_t
)object
)->ip_sorights
);
620 panic("ipc_object_copyin_from_kernel: strange rights");
625 * Routine: ipc_object_destroy
627 * Destroys a naked capability.
628 * Consumes a ref for the object.
630 * A receive right should be in limbo or in transit.
638 mach_msg_type_name_t msgt_name
)
640 assert(IO_VALID(object
));
641 assert(io_otype(object
) == IOT_PORT
);
644 case MACH_MSG_TYPE_PORT_SEND
:
645 ipc_port_release_send((ipc_port_t
) object
);
648 case MACH_MSG_TYPE_PORT_SEND_ONCE
:
649 ipc_notify_send_once((ipc_port_t
) object
);
652 case MACH_MSG_TYPE_PORT_RECEIVE
:
653 ipc_port_release_receive((ipc_port_t
) object
);
657 panic("ipc_object_destroy: strange rights");
662 * Routine: ipc_object_copyout
664 * Copyout a capability, placing it into a space.
665 * If successful, consumes a ref for the object.
669 * KERN_SUCCESS Copied out object, consumed ref.
670 * KERN_INVALID_TASK The space is dead.
671 * KERN_INVALID_CAPABILITY The object is dead.
672 * KERN_NO_SPACE No room in space for another right.
673 * KERN_RESOURCE_SHORTAGE No memory available.
674 * KERN_UREFS_OVERFLOW Urefs limit exceeded
675 * and overflow wasn't specified.
682 mach_msg_type_name_t msgt_name
,
684 mach_port_name_t
*namep
)
686 mach_port_name_t name
;
690 assert(IO_VALID(object
));
691 assert(io_otype(object
) == IOT_PORT
);
693 is_write_lock(space
);
696 if (!space
->is_active
) {
697 is_write_unlock(space
);
698 return KERN_INVALID_TASK
;
701 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
702 ipc_right_reverse(space
, object
, &name
, &entry
)) {
703 /* object is locked and active */
705 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
709 name
= (mach_port_name_t
)object
;
710 kr
= ipc_entry_get(space
, &name
, &entry
);
711 if (kr
!= KERN_SUCCESS
) {
712 /* unlocks/locks space, so must start again */
714 kr
= ipc_entry_grow_table(space
, ITS_SIZE_NONE
);
715 if (kr
!= KERN_SUCCESS
)
716 return kr
; /* space is unlocked */
721 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
722 assert(entry
->ie_object
== IO_NULL
);
725 if (!io_active(object
)) {
727 ipc_entry_dealloc(space
, name
, entry
);
728 is_write_unlock(space
);
729 return KERN_INVALID_CAPABILITY
;
732 entry
->ie_object
= object
;
736 /* space is write-locked and active, object is locked and active */
738 kr
= ipc_right_copyout(space
, name
, entry
,
739 msgt_name
, overflow
, object
);
740 /* object is unlocked */
741 is_write_unlock(space
);
743 if (kr
== KERN_SUCCESS
)
749 * Routine: ipc_object_copyout_name
751 * Copyout a capability, placing it into a space.
752 * The specified name is used for the capability.
753 * If successful, consumes a ref for the object.
757 * KERN_SUCCESS Copied out object, consumed ref.
758 * KERN_INVALID_TASK The space is dead.
759 * KERN_INVALID_CAPABILITY The object is dead.
760 * KERN_RESOURCE_SHORTAGE No memory available.
761 * KERN_UREFS_OVERFLOW Urefs limit exceeded
762 * and overflow wasn't specified.
763 * KERN_RIGHT_EXISTS Space has rights under another name.
764 * KERN_NAME_EXISTS Name is already used.
768 ipc_object_copyout_name(
771 mach_msg_type_name_t msgt_name
,
773 mach_port_name_t name
)
775 mach_port_name_t oname
;
780 assert(IO_VALID(object
));
781 assert(io_otype(object
) == IOT_PORT
);
783 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
784 if (kr
!= KERN_SUCCESS
)
786 /* space is write-locked and active */
788 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
789 ipc_right_reverse(space
, object
, &oname
, &oentry
)) {
790 /* object is locked and active */
795 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
796 ipc_entry_dealloc(space
, name
, entry
);
798 is_write_unlock(space
);
799 return KERN_RIGHT_EXISTS
;
802 assert(entry
== oentry
);
803 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
805 if (ipc_right_inuse(space
, name
, entry
))
806 return KERN_NAME_EXISTS
;
808 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
809 assert(entry
->ie_object
== IO_NULL
);
812 if (!io_active(object
)) {
814 ipc_entry_dealloc(space
, name
, entry
);
815 is_write_unlock(space
);
816 return KERN_INVALID_CAPABILITY
;
819 entry
->ie_object
= object
;
822 /* space is write-locked and active, object is locked and active */
824 kr
= ipc_right_copyout(space
, name
, entry
,
825 msgt_name
, overflow
, object
);
826 /* object is unlocked */
827 is_write_unlock(space
);
832 * Routine: ipc_object_copyout_dest
834 * Translates/consumes the destination right of a message.
835 * This is unlike normal copyout because the right is consumed
836 * in a funny way instead of being given to the receiving space.
837 * The receiver gets his name for the port, if he has receive
838 * rights, otherwise MACH_PORT_NULL.
840 * The object is locked and active. Nothing else locked.
841 * The object is unlocked and loses a reference.
845 ipc_object_copyout_dest(
848 mach_msg_type_name_t msgt_name
,
849 mach_port_name_t
*namep
)
851 mach_port_name_t name
;
853 assert(IO_VALID(object
));
854 assert(io_active(object
));
859 * If the space is the receiver/owner of the object,
860 * then we quietly consume the right and return
861 * the space's name for the object. Otherwise
862 * we destroy the right and return MACH_PORT_NULL.
866 case MACH_MSG_TYPE_PORT_SEND
: {
867 ipc_port_t port
= (ipc_port_t
) object
;
868 ipc_port_t nsrequest
= IP_NULL
;
869 mach_port_mscount_t mscount
;
871 if (port
->ip_receiver
== space
)
872 name
= port
->ip_receiver_name
;
874 name
= MACH_PORT_NULL
;
876 assert(port
->ip_srights
> 0);
877 if (--port
->ip_srights
== 0 &&
878 port
->ip_nsrequest
!= IP_NULL
) {
879 nsrequest
= port
->ip_nsrequest
;
880 port
->ip_nsrequest
= IP_NULL
;
881 mscount
= port
->ip_mscount
;
883 ipc_notify_no_senders(nsrequest
, mscount
);
889 case MACH_MSG_TYPE_PORT_SEND_ONCE
: {
890 ipc_port_t port
= (ipc_port_t
) object
;
892 assert(port
->ip_sorights
> 0);
894 if (port
->ip_receiver
== space
) {
895 /* quietly consume the send-once right */
898 name
= port
->ip_receiver_name
;
902 * A very bizarre case. The message
903 * was received, but before this copyout
904 * happened the space lost receive rights.
905 * We can't quietly consume the soright
906 * out from underneath some other task,
907 * so generate a send-once notification.
910 ip_reference(port
); /* restore ref */
913 ipc_notify_send_once(port
);
914 name
= MACH_PORT_NULL
;
921 panic("ipc_object_copyout_dest: strange rights");
922 name
= MACH_PORT_DEAD
;
929 * Routine: ipc_object_rename
931 * Rename an entry in a space.
935 * KERN_SUCCESS Renamed the entry.
936 * KERN_INVALID_TASK The space was dead.
937 * KERN_INVALID_NAME oname didn't denote an entry.
938 * KERN_NAME_EXISTS nname already denoted an entry.
939 * KERN_RESOURCE_SHORTAGE Couldn't allocate new entry.
945 mach_port_name_t oname
,
946 mach_port_name_t nname
)
948 ipc_entry_t oentry
, nentry
;
951 kr
= ipc_entry_alloc_name(space
, nname
, &nentry
);
952 if (kr
!= KERN_SUCCESS
)
955 /* space is write-locked and active */
957 if (ipc_right_inuse(space
, nname
, nentry
)) {
958 /* space is unlocked */
959 return KERN_NAME_EXISTS
;
962 /* don't let ipc_entry_lookup see the uninitialized new entry */
964 if ((oname
== nname
) ||
965 ((oentry
= ipc_entry_lookup(space
, oname
)) == IE_NULL
)) {
966 ipc_entry_dealloc(space
, nname
, nentry
);
967 is_write_unlock(space
);
968 return KERN_INVALID_NAME
;
971 kr
= ipc_right_rename(space
, oname
, oentry
, nname
, nentry
);
972 /* space is unlocked */
978 * Check whether the object is a port if so, free it. But
979 * keep track of that fact.
988 if (otype
== IOT_PORT
) {
989 port
= (ipc_port_t
) object
;
991 ipc_port_track_dealloc(port
);
992 #endif /* MACH_ASSERT */
994 zfree(ipc_object_zones
[otype
], object
);
996 #endif /* MACH_ASSERT */
998 #include <mach_kdb.h>
1001 #include <ddb/db_output.h>
1002 #include <kern/ipc_kobject.h>
1004 #define printf kdbprintf
1007 * Routine: ipc_object_print
1009 * Pretty-print an object for kdb.
1012 const char *ikot_print_array
[IKOT_MAX_TYPE
] = {
1023 "(DEVICE) ", /* 10 */
1033 "(ACTIVATION) ", /* 20 */
1039 "(CLOCK_CTRL) ", /* 26 */
1040 "(IOKIT_SPARE) ", /* 27 */
1041 "(NAMED_MEM_ENTRY) ", /* 28 */
1043 "(IOKIT_OBJECT) ", /* 30 */
1045 /* << new entries here */
1046 "(UNKNOWN) " /* magic catchall */
1048 /* Please keep in sync with kern/ipc_kobject.h */
1052 ipc_object_t object
)
1056 iprintf("%s", io_active(object
) ? "active" : "dead");
1057 printf(", refs=%d", object
->io_references
);
1058 printf(", otype=%d", io_otype(object
));
1059 kotype
= io_kotype(object
);
1060 if (kotype
>= 0 && kotype
< IKOT_MAX_TYPE
)
1061 printf(", kotype=%d %s\n", io_kotype(object
),
1062 ikot_print_array
[kotype
]);
1064 printf(", kotype=0x%x %s\n", io_kotype(object
),
1065 ikot_print_array
[IKOT_UNKNOWN
]);
1068 #endif /* MACH_KDB */