2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
31 * All Rights Reserved.
33 * Permission to use, copy, modify and distribute this software and its
34 * documentation is hereby granted, provided that both the copyright
35 * notice and this permission notice appear in all copies of the
36 * software, derivative works or modified versions, and any portions
37 * thereof, and that both notices appear in supporting documentation.
39 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
40 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
41 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
43 * Carnegie Mellon requests users of this software to return to
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
56 * File: ipc/ipc_notify.c
60 * Notification-sending functions.
65 #include <mach/port.h>
66 #include <mach/message.h>
67 #include <mach/notify.h>
68 #include <kern/assert.h>
69 #include <kern/misc_protos.h>
70 #include <ipc/ipc_kmsg.h>
71 #include <ipc/ipc_mqueue.h>
72 #include <ipc/ipc_notify.h>
73 #include <ipc/ipc_port.h>
76 * Forward declarations
78 void ipc_notify_init_port_deleted(
79 mach_port_deleted_notification_t
*n
);
81 void ipc_notify_init_port_destroyed(
82 mach_port_destroyed_notification_t
*n
);
84 void ipc_notify_init_no_senders(
85 mach_no_senders_notification_t
*n
);
87 void ipc_notify_init_send_once(
88 mach_send_once_notification_t
*n
);
90 void ipc_notify_init_dead_name(
91 mach_dead_name_notification_t
*n
);
93 mach_port_deleted_notification_t ipc_notify_port_deleted_template
;
94 mach_port_destroyed_notification_t ipc_notify_port_destroyed_template
;
95 mach_no_senders_notification_t ipc_notify_no_senders_template
;
96 mach_send_once_notification_t ipc_notify_send_once_template
;
97 mach_dead_name_notification_t ipc_notify_dead_name_template
;
100 * Routine: ipc_notify_init_port_deleted
102 * Initialize a template for port-deleted notifications.
106 ipc_notify_init_port_deleted(
107 mach_port_deleted_notification_t
*n
)
109 mach_msg_header_t
*m
= &n
->not_header
;
111 m
->msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE
, 0);
112 m
->msgh_local_port
= MACH_PORT_NULL
;
113 m
->msgh_remote_port
= MACH_PORT_NULL
;
114 m
->msgh_id
= MACH_NOTIFY_PORT_DELETED
;
115 m
->msgh_size
= ((int)sizeof *n
) - sizeof(mach_msg_format_0_trailer_t
);
117 n
->not_port
= MACH_PORT_NULL
;
119 n
->trailer
.msgh_seqno
= 0;
120 n
->trailer
.msgh_sender
= KERNEL_SECURITY_TOKEN
;
121 n
->trailer
.msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
122 n
->trailer
.msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
126 * Routine: ipc_notify_init_port_destroyed
128 * Initialize a template for port-destroyed notifications.
132 ipc_notify_init_port_destroyed(
133 mach_port_destroyed_notification_t
*n
)
135 mach_msg_header_t
*m
= &n
->not_header
;
137 m
->msgh_bits
= MACH_MSGH_BITS_COMPLEX
|
138 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE
, 0);
139 m
->msgh_local_port
= MACH_PORT_NULL
;
140 m
->msgh_remote_port
= MACH_PORT_NULL
;
141 m
->msgh_id
= MACH_NOTIFY_PORT_DESTROYED
;
142 m
->msgh_size
= ((int)sizeof *n
) - sizeof(mach_msg_format_0_trailer_t
);
144 n
->not_body
.msgh_descriptor_count
= 1;
145 n
->not_port
.disposition
= MACH_MSG_TYPE_PORT_RECEIVE
;
146 n
->not_port
.name
= MACH_PORT_NULL
;
147 n
->not_port
.type
= MACH_MSG_PORT_DESCRIPTOR
;
148 n
->trailer
.msgh_seqno
= 0;
149 n
->trailer
.msgh_sender
= KERNEL_SECURITY_TOKEN
;
150 n
->trailer
.msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
151 n
->trailer
.msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
155 * Routine: ipc_notify_init_no_senders
157 * Initialize a template for no-senders notifications.
161 ipc_notify_init_no_senders(
162 mach_no_senders_notification_t
*n
)
164 mach_msg_header_t
*m
= &n
->not_header
;
166 m
->msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE
, 0);
167 m
->msgh_local_port
= MACH_PORT_NULL
;
168 m
->msgh_remote_port
= MACH_PORT_NULL
;
169 m
->msgh_id
= MACH_NOTIFY_NO_SENDERS
;
170 m
->msgh_size
= ((int)sizeof *n
) - sizeof(mach_msg_format_0_trailer_t
);
173 n
->trailer
.msgh_seqno
= 0;
174 n
->trailer
.msgh_sender
= KERNEL_SECURITY_TOKEN
;
175 n
->trailer
.msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
176 n
->trailer
.msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
181 * Routine: ipc_notify_init_send_once
183 * Initialize a template for send-once notifications.
187 ipc_notify_init_send_once(
188 mach_send_once_notification_t
*n
)
190 mach_msg_header_t
*m
= &n
->not_header
;
192 m
->msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE
, 0);
193 m
->msgh_local_port
= MACH_PORT_NULL
;
194 m
->msgh_remote_port
= MACH_PORT_NULL
;
195 m
->msgh_id
= MACH_NOTIFY_SEND_ONCE
;
196 m
->msgh_size
= ((int)sizeof *n
) - sizeof(mach_msg_format_0_trailer_t
);
197 n
->trailer
.msgh_seqno
= 0;
198 n
->trailer
.msgh_sender
= KERNEL_SECURITY_TOKEN
;
199 n
->trailer
.msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
200 n
->trailer
.msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
204 * Routine: ipc_notify_init_dead_name
206 * Initialize a template for dead-name notifications.
210 ipc_notify_init_dead_name(
211 mach_dead_name_notification_t
*n
)
213 mach_msg_header_t
*m
= &n
->not_header
;
215 m
->msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE
, 0);
216 m
->msgh_local_port
= MACH_PORT_NULL
;
217 m
->msgh_remote_port
= MACH_PORT_NULL
;
218 m
->msgh_id
= MACH_NOTIFY_DEAD_NAME
;
219 m
->msgh_size
= ((int)sizeof *n
) - sizeof(mach_msg_format_0_trailer_t
);
221 n
->not_port
= MACH_PORT_NULL
;
223 n
->trailer
.msgh_seqno
= 0;
224 n
->trailer
.msgh_sender
= KERNEL_SECURITY_TOKEN
;
225 n
->trailer
.msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
226 n
->trailer
.msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
230 * Routine: ipc_notify_init
232 * Initialize the notification subsystem.
236 ipc_notify_init(void)
238 ipc_notify_init_port_deleted(&ipc_notify_port_deleted_template
);
239 ipc_notify_init_port_destroyed(&ipc_notify_port_destroyed_template
);
240 ipc_notify_init_no_senders(&ipc_notify_no_senders_template
);
241 ipc_notify_init_send_once(&ipc_notify_send_once_template
);
242 ipc_notify_init_dead_name(&ipc_notify_dead_name_template
);
246 * Routine: ipc_notify_port_deleted
248 * Send a port-deleted notification.
251 * Consumes a ref/soright for port.
255 ipc_notify_port_deleted(
257 mach_port_name_t name
)
260 mach_port_deleted_notification_t
*n
;
262 kmsg
= ipc_kmsg_alloc(sizeof *n
);
263 if (kmsg
== IKM_NULL
) {
264 printf("dropped port-deleted (0x%08x, 0x%x)\n", port
, name
);
265 ipc_port_release_sonce(port
);
269 n
= (mach_port_deleted_notification_t
*) &kmsg
->ikm_header
;
270 *n
= ipc_notify_port_deleted_template
;
272 n
->not_header
.msgh_remote_port
= port
;
275 ipc_kmsg_send_always(kmsg
);
279 * Routine: ipc_notify_port_destroyed
281 * Send a port-destroyed notification.
284 * Consumes a ref/soright for port.
285 * Consumes a ref for right, which should be a receive right
286 * prepped for placement into a message. (In-transit,
287 * or in-limbo if a circularity was detected.)
291 ipc_notify_port_destroyed(
296 mach_port_destroyed_notification_t
*n
;
298 kmsg
= ipc_kmsg_alloc(sizeof *n
);
299 if (kmsg
== IKM_NULL
) {
300 printf("dropped port-destroyed (0x%08x, 0x%08x)\n",
302 ipc_port_release_sonce(port
);
303 ipc_port_release_receive(right
);
307 n
= (mach_port_destroyed_notification_t
*) &kmsg
->ikm_header
;
308 *n
= ipc_notify_port_destroyed_template
;
310 n
->not_header
.msgh_remote_port
= port
;
311 n
->not_port
.name
= right
;
313 ipc_kmsg_send_always(kmsg
);
317 * Routine: ipc_notify_no_senders
319 * Send a no-senders notification.
322 * Consumes a ref/soright for port.
326 ipc_notify_no_senders(
328 mach_port_mscount_t mscount
)
331 mach_no_senders_notification_t
*n
;
333 kmsg
= ipc_kmsg_alloc(sizeof *n
);
334 if (kmsg
== IKM_NULL
) {
335 printf("dropped no-senders (0x%08x, %u)\n", port
, mscount
);
336 ipc_port_release_sonce(port
);
340 n
= (mach_no_senders_notification_t
*) &kmsg
->ikm_header
;
341 *n
= ipc_notify_no_senders_template
;
343 n
->not_header
.msgh_remote_port
= port
;
344 n
->not_count
= mscount
;
346 ipc_kmsg_send_always(kmsg
);
350 * Routine: ipc_notify_send_once
352 * Send a send-once notification.
355 * Consumes a ref/soright for port.
359 ipc_notify_send_once(
363 mach_send_once_notification_t
*n
;
365 kmsg
= ipc_kmsg_alloc(sizeof *n
);
366 if (kmsg
== IKM_NULL
) {
367 printf("dropped send-once (0x%08x)\n", port
);
368 ipc_port_release_sonce(port
);
372 n
= (mach_send_once_notification_t
*) &kmsg
->ikm_header
;
373 *n
= ipc_notify_send_once_template
;
375 n
->not_header
.msgh_remote_port
= port
;
377 ipc_kmsg_send_always(kmsg
);
381 * Routine: ipc_notify_dead_name
383 * Send a dead-name notification.
386 * Consumes a ref/soright for port.
390 ipc_notify_dead_name(
392 mach_port_name_t name
)
395 mach_dead_name_notification_t
*n
;
397 kmsg
= ipc_kmsg_alloc(sizeof *n
);
398 if (kmsg
== IKM_NULL
) {
399 printf("dropped dead-name (0x%08x, 0x%x)\n", port
, name
);
400 ipc_port_release_sonce(port
);
404 n
= (mach_dead_name_notification_t
*) &kmsg
->ikm_header
;
405 *n
= ipc_notify_dead_name_template
;
407 n
->not_header
.msgh_remote_port
= port
;
410 ipc_kmsg_send_always(kmsg
);