2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 * Mach Operating System
35 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
36 * All Rights Reserved.
38 * Permission to use, copy, modify and distribute this software and its
39 * documentation is hereby granted, provided that both the copyright
40 * notice and this permission notice appear in all copies of the
41 * software, derivative works or modified versions, and any portions
42 * thereof, and that both notices appear in supporting documentation.
44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
46 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 * Carnegie Mellon requests users of this software to return to
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science
52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
55 * any improvements or extensions that they make and grant Carnegie Mellon
56 * the rights to redistribute these changes.
61 * File: ipc/ipc_object.c
65 * Functions to manipulate IPC objects.
70 #include <mach/mach_types.h>
71 #include <mach/boolean.h>
72 #include <mach/kern_return.h>
73 #include <mach/port.h>
74 #include <mach/message.h>
76 #include <kern/kern_types.h>
77 #include <kern/misc_protos.h>
79 #include <ipc/ipc_types.h>
81 #include <ipc/ipc_space.h>
82 #include <ipc/ipc_entry.h>
83 #include <ipc/ipc_object.h>
84 #include <ipc/ipc_hash.h>
85 #include <ipc/ipc_right.h>
86 #include <ipc/ipc_notify.h>
87 #include <ipc/ipc_pset.h>
89 zone_t ipc_object_zones
[IOT_NUMBER
];
92 * Routine: ipc_object_reference
94 * Take a reference to an object.
102 assert(object
->io_references
> 0);
103 io_reference(object
);
108 * Routine: ipc_object_release
110 * Release a reference to an object.
118 assert(object
->io_references
> 0);
120 io_check_unlock(object
);
124 * Routine: ipc_object_translate
126 * Look up an object in a space.
128 * Nothing locked before. If successful, the object
129 * is returned locked. The caller doesn't get a ref.
131 * KERN_SUCCESS Object returned locked.
132 * KERN_INVALID_TASK The space is dead.
133 * KERN_INVALID_NAME The name doesn't denote a right.
134 * KERN_INVALID_RIGHT Name doesn't denote the correct right.
138 ipc_object_translate(
140 mach_port_name_t name
,
141 mach_port_right_t right
,
142 ipc_object_t
*objectp
)
148 kr
= ipc_right_lookup_read(space
, name
, &entry
);
149 if (kr
!= KERN_SUCCESS
)
151 /* space is read-locked and active */
153 if ((entry
->ie_bits
& MACH_PORT_TYPE(right
)) == MACH_PORT_TYPE_NONE
) {
154 is_read_unlock(space
);
155 return KERN_INVALID_RIGHT
;
158 object
= entry
->ie_object
;
159 assert(object
!= IO_NULL
);
162 is_read_unlock(space
);
169 * Routine: ipc_object_translate_two
171 * Look up two objects in a space.
173 * Nothing locked before. If successful, the objects
174 * are returned locked. The caller doesn't get a ref.
176 * KERN_SUCCESS Objects returned locked.
177 * KERN_INVALID_TASK The space is dead.
178 * KERN_INVALID_NAME A name doesn't denote a right.
179 * KERN_INVALID_RIGHT A name doesn't denote the correct right.
183 ipc_object_translate_two(
185 mach_port_name_t name1
,
186 mach_port_right_t right1
,
187 ipc_object_t
*objectp1
,
188 mach_port_name_t name2
,
189 mach_port_right_t right2
,
190 ipc_object_t
*objectp2
)
197 kr
= ipc_right_lookup_two_read(space
, name1
, &entry1
, name2
, &entry2
);
198 if (kr
!= KERN_SUCCESS
)
200 /* space is read-locked and active */
202 if ((entry1
->ie_bits
& MACH_PORT_TYPE(right1
)) == MACH_PORT_TYPE_NONE
) {
203 is_read_unlock(space
);
204 return KERN_INVALID_RIGHT
;
207 if ((entry2
->ie_bits
& MACH_PORT_TYPE(right2
)) == MACH_PORT_TYPE_NONE
) {
208 is_read_unlock(space
);
209 return KERN_INVALID_RIGHT
;
212 object
= entry1
->ie_object
;
213 assert(object
!= IO_NULL
);
217 object
= entry2
->ie_object
;
218 assert(object
!= IO_NULL
);
222 is_read_unlock(space
);
227 * Routine: ipc_object_alloc_dead
229 * Allocate a dead-name entry.
233 * KERN_SUCCESS The dead name is allocated.
234 * KERN_INVALID_TASK The space is dead.
235 * KERN_NO_SPACE No room for an entry in the space.
236 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
240 ipc_object_alloc_dead(
242 mach_port_name_t
*namep
)
247 kr
= ipc_entry_alloc(space
, namep
, &entry
);
248 if (kr
!= KERN_SUCCESS
)
250 /* space is write-locked */
252 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
254 assert(entry
->ie_object
== IO_NULL
);
255 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
257 is_write_unlock(space
);
262 * Routine: ipc_object_alloc_dead_name
264 * Allocate a dead-name entry, with a specific name.
268 * KERN_SUCCESS The dead name is allocated.
269 * KERN_INVALID_TASK The space is dead.
270 * KERN_NAME_EXISTS The name already denotes a right.
271 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
275 ipc_object_alloc_dead_name(
277 mach_port_name_t name
)
282 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
283 if (kr
!= KERN_SUCCESS
)
285 /* space is write-locked */
287 if (ipc_right_inuse(space
, name
, entry
))
288 return KERN_NAME_EXISTS
;
290 /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
292 assert(entry
->ie_object
== IO_NULL
);
293 entry
->ie_bits
|= MACH_PORT_TYPE_DEAD_NAME
| 1;
295 is_write_unlock(space
);
300 * Routine: ipc_object_alloc
302 * Allocate an object.
304 * Nothing locked. If successful, the object is returned locked.
305 * The caller doesn't get a reference for the object.
307 * KERN_SUCCESS The object is allocated.
308 * KERN_INVALID_TASK The space is dead.
309 * KERN_NO_SPACE No room for an entry in the space.
310 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
316 ipc_object_type_t otype
,
317 mach_port_type_t type
,
318 mach_port_urefs_t urefs
,
319 mach_port_name_t
*namep
,
320 ipc_object_t
*objectp
)
326 assert(otype
< IOT_NUMBER
);
327 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
328 assert(type
!= MACH_PORT_TYPE_NONE
);
329 assert(urefs
<= MACH_PORT_UREFS_MAX
);
331 object
= io_alloc(otype
);
332 if (object
== IO_NULL
)
333 return KERN_RESOURCE_SHORTAGE
;
335 if (otype
== IOT_PORT
) {
336 ipc_port_t port
= (ipc_port_t
)object
;
338 bzero((char *)port
, sizeof(*port
));
339 } else if (otype
== IOT_PORT_SET
) {
340 ipc_pset_t pset
= (ipc_pset_t
)object
;
342 bzero((char *)pset
, sizeof(*pset
));
345 io_lock_init(object
);
346 *namep
= (mach_port_name_t
)object
;
347 kr
= ipc_entry_alloc(space
, namep
, &entry
);
348 if (kr
!= KERN_SUCCESS
) {
349 io_free(otype
, object
);
352 /* space is write-locked */
354 entry
->ie_bits
|= type
| urefs
;
355 entry
->ie_object
= object
;
358 is_write_unlock(space
);
360 object
->io_references
= 1; /* for entry, not caller */
361 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
368 * Routine: ipc_object_alloc_name
370 * Allocate an object, with a specific name.
372 * Nothing locked. If successful, the object is returned locked.
373 * The caller doesn't get a reference for the object.
375 * KERN_SUCCESS The object is allocated.
376 * KERN_INVALID_TASK The space is dead.
377 * KERN_NAME_EXISTS The name already denotes a right.
378 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
382 ipc_object_alloc_name(
384 ipc_object_type_t otype
,
385 mach_port_type_t type
,
386 mach_port_urefs_t urefs
,
387 mach_port_name_t name
,
388 ipc_object_t
*objectp
)
394 assert(otype
< IOT_NUMBER
);
395 assert((type
& MACH_PORT_TYPE_ALL_RIGHTS
) == type
);
396 assert(type
!= MACH_PORT_TYPE_NONE
);
397 assert(urefs
<= MACH_PORT_UREFS_MAX
);
399 object
= io_alloc(otype
);
400 if (object
== IO_NULL
)
401 return KERN_RESOURCE_SHORTAGE
;
403 if (otype
== IOT_PORT
) {
404 ipc_port_t port
= (ipc_port_t
)object
;
406 bzero((char *)port
, sizeof(*port
));
407 } else if (otype
== IOT_PORT_SET
) {
408 ipc_pset_t pset
= (ipc_pset_t
)object
;
410 bzero((char *)pset
, sizeof(*pset
));
413 io_lock_init(object
);
414 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
415 if (kr
!= KERN_SUCCESS
) {
416 io_free(otype
, object
);
419 /* space is write-locked */
421 if (ipc_right_inuse(space
, name
, entry
)) {
422 io_free(otype
, object
);
423 return KERN_NAME_EXISTS
;
426 entry
->ie_bits
|= type
| urefs
;
427 entry
->ie_object
= object
;
430 is_write_unlock(space
);
432 object
->io_references
= 1; /* for entry, not caller */
433 object
->io_bits
= io_makebits(TRUE
, otype
, 0);
440 * Routine: ipc_object_copyin_type
442 * Convert a send type name to a received type name.
446 ipc_object_copyin_type(
447 mach_msg_type_name_t msgt_name
)
451 case MACH_MSG_TYPE_MOVE_RECEIVE
:
452 case MACH_MSG_TYPE_COPY_RECEIVE
:
453 return MACH_MSG_TYPE_PORT_RECEIVE
;
455 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
456 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
457 return MACH_MSG_TYPE_PORT_SEND_ONCE
;
459 case MACH_MSG_TYPE_MOVE_SEND
:
460 case MACH_MSG_TYPE_MAKE_SEND
:
461 case MACH_MSG_TYPE_COPY_SEND
:
462 return MACH_MSG_TYPE_PORT_SEND
;
465 return MACH_MSG_TYPE_PORT_NONE
;
470 * Routine: ipc_object_copyin
472 * Copyin a capability from a space.
473 * If successful, the caller gets a ref
474 * for the resulting object, unless it is IO_DEAD.
478 * KERN_SUCCESS Acquired an object, possibly IO_DEAD.
479 * KERN_INVALID_TASK The space is dead.
480 * KERN_INVALID_NAME Name doesn't exist in space.
481 * KERN_INVALID_RIGHT Name doesn't denote correct right.
487 mach_port_name_t name
,
488 mach_msg_type_name_t msgt_name
,
489 ipc_object_t
*objectp
)
496 * Could first try a read lock when doing
497 * MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND,
498 * and MACH_MSG_TYPE_MAKE_SEND_ONCE.
501 kr
= ipc_right_lookup_write(space
, name
, &entry
);
502 if (kr
!= KERN_SUCCESS
)
504 /* space is write-locked and active */
506 kr
= ipc_right_copyin(space
, name
, entry
,
509 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
510 ipc_entry_dealloc(space
, name
, entry
);
511 is_write_unlock(space
);
513 if ((kr
== KERN_SUCCESS
) && (soright
!= IP_NULL
))
514 ipc_notify_port_deleted(soright
, name
);
520 * Routine: ipc_object_copyin_from_kernel
522 * Copyin a naked capability from the kernel.
524 * MACH_MSG_TYPE_MOVE_RECEIVE
525 * The receiver must be ipc_space_kernel
526 * or the receive right must already be in limbo.
527 * Consumes the naked receive right.
528 * MACH_MSG_TYPE_COPY_SEND
529 * A naked send right must be supplied.
530 * The port gains a reference, and a send right
531 * if the port is still active.
532 * MACH_MSG_TYPE_MAKE_SEND
533 * The receiver must be ipc_space_kernel.
534 * The port gains a reference and a send right.
535 * MACH_MSG_TYPE_MOVE_SEND
536 * Consumes a naked send right.
537 * MACH_MSG_TYPE_MAKE_SEND_ONCE
538 * The port gains a reference and a send-once right.
539 * Receiver also be the caller of device subsystem,
541 * MACH_MSG_TYPE_MOVE_SEND_ONCE
542 * Consumes a naked send-once right.
548 ipc_object_copyin_from_kernel(
550 mach_msg_type_name_t msgt_name
)
552 assert(IO_VALID(object
));
555 case MACH_MSG_TYPE_MOVE_RECEIVE
: {
556 ipc_port_t port
= (ipc_port_t
) object
;
559 assert(ip_active(port
));
560 if (port
->ip_destination
!= IP_NULL
) {
561 assert(port
->ip_receiver
== ipc_space_kernel
);
563 /* relevant part of ipc_port_clear_receiver */
564 ipc_port_set_mscount(port
, 0);
566 port
->ip_receiver_name
= MACH_PORT_NULL
;
567 port
->ip_destination
= IP_NULL
;
573 case MACH_MSG_TYPE_COPY_SEND
: {
574 ipc_port_t port
= (ipc_port_t
) object
;
577 if (ip_active(port
)) {
578 assert(port
->ip_srights
> 0);
586 case MACH_MSG_TYPE_MAKE_SEND
: {
587 ipc_port_t port
= (ipc_port_t
) object
;
590 assert(ip_active(port
));
591 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
592 assert(port
->ip_receiver
== ipc_space_kernel
);
601 case MACH_MSG_TYPE_MOVE_SEND
: {
602 /* move naked send right into the message */
603 assert(((ipc_port_t
)object
)->ip_srights
);
607 case MACH_MSG_TYPE_MAKE_SEND_ONCE
: {
608 ipc_port_t port
= (ipc_port_t
) object
;
611 assert(ip_active(port
));
612 assert(port
->ip_receiver_name
!= MACH_PORT_NULL
);
620 case MACH_MSG_TYPE_MOVE_SEND_ONCE
: {
621 /* move naked send-once right into the message */
622 assert(((ipc_port_t
)object
)->ip_sorights
);
627 panic("ipc_object_copyin_from_kernel: strange rights");
632 * Routine: ipc_object_destroy
634 * Destroys a naked capability.
635 * Consumes a ref for the object.
637 * A receive right should be in limbo or in transit.
645 mach_msg_type_name_t msgt_name
)
647 assert(IO_VALID(object
));
648 assert(io_otype(object
) == IOT_PORT
);
651 case MACH_MSG_TYPE_PORT_SEND
:
652 ipc_port_release_send((ipc_port_t
) object
);
655 case MACH_MSG_TYPE_PORT_SEND_ONCE
:
656 ipc_notify_send_once((ipc_port_t
) object
);
659 case MACH_MSG_TYPE_PORT_RECEIVE
:
660 ipc_port_release_receive((ipc_port_t
) object
);
664 panic("ipc_object_destroy: strange rights");
669 * Routine: ipc_object_copyout
671 * Copyout a capability, placing it into a space.
672 * If successful, consumes a ref for the object.
676 * KERN_SUCCESS Copied out object, consumed ref.
677 * KERN_INVALID_TASK The space is dead.
678 * KERN_INVALID_CAPABILITY The object is dead.
679 * KERN_NO_SPACE No room in space for another right.
680 * KERN_RESOURCE_SHORTAGE No memory available.
681 * KERN_UREFS_OVERFLOW Urefs limit exceeded
682 * and overflow wasn't specified.
689 mach_msg_type_name_t msgt_name
,
691 mach_port_name_t
*namep
)
693 mach_port_name_t name
;
697 assert(IO_VALID(object
));
698 assert(io_otype(object
) == IOT_PORT
);
700 is_write_lock(space
);
703 if (!space
->is_active
) {
704 is_write_unlock(space
);
705 return KERN_INVALID_TASK
;
708 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
709 ipc_right_reverse(space
, object
, &name
, &entry
)) {
710 /* object is locked and active */
712 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
716 name
= (mach_port_name_t
)object
;
717 kr
= ipc_entry_get(space
, &name
, &entry
);
718 if (kr
!= KERN_SUCCESS
) {
719 /* unlocks/locks space, so must start again */
721 kr
= ipc_entry_grow_table(space
, ITS_SIZE_NONE
);
722 if (kr
!= KERN_SUCCESS
)
723 return kr
; /* space is unlocked */
728 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
729 assert(entry
->ie_object
== IO_NULL
);
732 if (!io_active(object
)) {
734 ipc_entry_dealloc(space
, name
, entry
);
735 is_write_unlock(space
);
736 return KERN_INVALID_CAPABILITY
;
739 entry
->ie_object
= object
;
743 /* space is write-locked and active, object is locked and active */
745 kr
= ipc_right_copyout(space
, name
, entry
,
746 msgt_name
, overflow
, object
);
747 /* object is unlocked */
748 is_write_unlock(space
);
750 if (kr
== KERN_SUCCESS
)
756 * Routine: ipc_object_copyout_name
758 * Copyout a capability, placing it into a space.
759 * The specified name is used for the capability.
760 * If successful, consumes a ref for the object.
764 * KERN_SUCCESS Copied out object, consumed ref.
765 * KERN_INVALID_TASK The space is dead.
766 * KERN_INVALID_CAPABILITY The object is dead.
767 * KERN_RESOURCE_SHORTAGE No memory available.
768 * KERN_UREFS_OVERFLOW Urefs limit exceeded
769 * and overflow wasn't specified.
770 * KERN_RIGHT_EXISTS Space has rights under another name.
771 * KERN_NAME_EXISTS Name is already used.
775 ipc_object_copyout_name(
778 mach_msg_type_name_t msgt_name
,
780 mach_port_name_t name
)
782 mach_port_name_t oname
;
787 assert(IO_VALID(object
));
788 assert(io_otype(object
) == IOT_PORT
);
790 kr
= ipc_entry_alloc_name(space
, name
, &entry
);
791 if (kr
!= KERN_SUCCESS
)
793 /* space is write-locked and active */
795 if ((msgt_name
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
796 ipc_right_reverse(space
, object
, &oname
, &oentry
)) {
797 /* object is locked and active */
802 if (IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
)
803 ipc_entry_dealloc(space
, name
, entry
);
805 is_write_unlock(space
);
806 return KERN_RIGHT_EXISTS
;
809 assert(entry
== oentry
);
810 assert(entry
->ie_bits
& MACH_PORT_TYPE_SEND_RECEIVE
);
812 if (ipc_right_inuse(space
, name
, entry
))
813 return KERN_NAME_EXISTS
;
815 assert(IE_BITS_TYPE(entry
->ie_bits
) == MACH_PORT_TYPE_NONE
);
816 assert(entry
->ie_object
== IO_NULL
);
819 if (!io_active(object
)) {
821 ipc_entry_dealloc(space
, name
, entry
);
822 is_write_unlock(space
);
823 return KERN_INVALID_CAPABILITY
;
826 entry
->ie_object
= object
;
829 /* space is write-locked and active, object is locked and active */
831 kr
= ipc_right_copyout(space
, name
, entry
,
832 msgt_name
, overflow
, object
);
833 /* object is unlocked */
834 is_write_unlock(space
);
839 * Routine: ipc_object_copyout_dest
841 * Translates/consumes the destination right of a message.
842 * This is unlike normal copyout because the right is consumed
843 * in a funny way instead of being given to the receiving space.
844 * The receiver gets his name for the port, if he has receive
845 * rights, otherwise MACH_PORT_NULL.
847 * The object is locked and active. Nothing else locked.
848 * The object is unlocked and loses a reference.
852 ipc_object_copyout_dest(
855 mach_msg_type_name_t msgt_name
,
856 mach_port_name_t
*namep
)
858 mach_port_name_t name
;
860 assert(IO_VALID(object
));
861 assert(io_active(object
));
866 * If the space is the receiver/owner of the object,
867 * then we quietly consume the right and return
868 * the space's name for the object. Otherwise
869 * we destroy the right and return MACH_PORT_NULL.
873 case MACH_MSG_TYPE_PORT_SEND
: {
874 ipc_port_t port
= (ipc_port_t
) object
;
875 ipc_port_t nsrequest
= IP_NULL
;
876 mach_port_mscount_t mscount
;
878 if (port
->ip_receiver
== space
)
879 name
= port
->ip_receiver_name
;
881 name
= MACH_PORT_NULL
;
883 assert(port
->ip_srights
> 0);
884 if (--port
->ip_srights
== 0 &&
885 port
->ip_nsrequest
!= IP_NULL
) {
886 nsrequest
= port
->ip_nsrequest
;
887 port
->ip_nsrequest
= IP_NULL
;
888 mscount
= port
->ip_mscount
;
890 ipc_notify_no_senders(nsrequest
, mscount
);
896 case MACH_MSG_TYPE_PORT_SEND_ONCE
: {
897 ipc_port_t port
= (ipc_port_t
) object
;
899 assert(port
->ip_sorights
> 0);
901 if (port
->ip_receiver
== space
) {
902 /* quietly consume the send-once right */
905 name
= port
->ip_receiver_name
;
909 * A very bizarre case. The message
910 * was received, but before this copyout
911 * happened the space lost receive rights.
912 * We can't quietly consume the soright
913 * out from underneath some other task,
914 * so generate a send-once notification.
917 ip_reference(port
); /* restore ref */
920 ipc_notify_send_once(port
);
921 name
= MACH_PORT_NULL
;
928 panic("ipc_object_copyout_dest: strange rights");
929 name
= MACH_PORT_DEAD
;
936 * Routine: ipc_object_rename
938 * Rename an entry in a space.
942 * KERN_SUCCESS Renamed the entry.
943 * KERN_INVALID_TASK The space was dead.
944 * KERN_INVALID_NAME oname didn't denote an entry.
945 * KERN_NAME_EXISTS nname already denoted an entry.
946 * KERN_RESOURCE_SHORTAGE Couldn't allocate new entry.
952 mach_port_name_t oname
,
953 mach_port_name_t nname
)
955 ipc_entry_t oentry
, nentry
;
958 kr
= ipc_entry_alloc_name(space
, nname
, &nentry
);
959 if (kr
!= KERN_SUCCESS
)
962 /* space is write-locked and active */
964 if (ipc_right_inuse(space
, nname
, nentry
)) {
965 /* space is unlocked */
966 return KERN_NAME_EXISTS
;
969 /* don't let ipc_entry_lookup see the uninitialized new entry */
971 if ((oname
== nname
) ||
972 ((oentry
= ipc_entry_lookup(space
, oname
)) == IE_NULL
)) {
973 ipc_entry_dealloc(space
, nname
, nentry
);
974 is_write_unlock(space
);
975 return KERN_INVALID_NAME
;
978 kr
= ipc_right_rename(space
, oname
, oentry
, nname
, nentry
);
979 /* space is unlocked */
985 * Check whether the object is a port if so, free it. But
986 * keep track of that fact.
995 if (otype
== IOT_PORT
) {
996 port
= (ipc_port_t
) object
;
998 ipc_port_track_dealloc(port
);
999 #endif /* MACH_ASSERT */
1001 zfree(ipc_object_zones
[otype
], object
);
1003 #endif /* MACH_ASSERT */
1005 #include <mach_kdb.h>
1008 #include <ddb/db_output.h>
1009 #include <kern/ipc_kobject.h>
1011 #define printf kdbprintf
1014 * Routine: ipc_object_print
1016 * Pretty-print an object for kdb.
1019 const char *ikot_print_array
[IKOT_MAX_TYPE
] = {
1030 "(DEVICE) ", /* 10 */
1040 "(ACTIVATION) ", /* 20 */
1046 "(CLOCK_CTRL) ", /* 26 */
1047 "(IOKIT_SPARE) ", /* 27 */
1048 "(NAMED_MEM_ENTRY) ", /* 28 */
1050 "(IOKIT_OBJECT) ", /* 30 */
1052 "(MEM_OBJ_CONTROL) ",
1054 * Add new entries here.
1055 * Please keep in sync with kern/ipc_kobject.h
1057 "(UNKNOWN) " /* magic catchall */
1062 ipc_object_t object
)
1066 iprintf("%s", io_active(object
) ? "active" : "dead");
1067 printf(", refs=%d", object
->io_references
);
1068 printf(", otype=%d", io_otype(object
));
1069 kotype
= io_kotype(object
);
1070 if (kotype
>= 0 && kotype
< IKOT_MAX_TYPE
)
1071 printf(", kotype=%d %s\n", io_kotype(object
),
1072 ikot_print_array
[kotype
]);
1074 printf(", kotype=0x%x %s\n", io_kotype(object
),
1075 ikot_print_array
[IKOT_UNKNOWN
]);
1078 #endif /* MACH_KDB */