|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 6: * Permission to use, copy, modify and distribute this software and its 7: * documentation is hereby granted, provided that both the copyright 8: * notice and this permission notice appear in all copies of the 9: * software, derivative works or modified versions, and any portions 10: * thereof, and that both notices appear in supporting documentation. 1.1.1.2 ! root 11: * 1.1 root 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon 24: * the rights to redistribute these changes. 25: */ 26: /* 27: * File: ipc/ipc_notify.c 28: * Author: Rich Draves 29: * Date: 1989 30: * 31: * Notification-sending functions. 32: */ 33: 34: #include <mach_ipc_compat.h> 35: 36: #include <mach/port.h> 37: #include <mach/message.h> 38: #include <mach/notify.h> 39: #include <kern/assert.h> 40: #include <ipc/ipc_kmsg.h> 41: #include <ipc/ipc_mqueue.h> 42: #include <ipc/ipc_notify.h> 43: #include <ipc/ipc_port.h> 44: 45: #include <ipc/ipc_machdep.h> 46: 47: mach_port_deleted_notification_t ipc_notify_port_deleted_template; 48: mach_msg_accepted_notification_t ipc_notify_msg_accepted_template; 49: mach_port_destroyed_notification_t ipc_notify_port_destroyed_template; 50: mach_no_senders_notification_t ipc_notify_no_senders_template; 51: mach_send_once_notification_t ipc_notify_send_once_template; 52: mach_dead_name_notification_t ipc_notify_dead_name_template; 53: 54: #if MACH_IPC_COMPAT 55: /* 56: * When notification messages are received via the old 57: * msg_receive trap, the msg_type field should contain 58: * MSG_TYPE_EMERGENCY. We arrange for this by putting 59: * MSG_TYPE_EMERGENCY into msgh_seqno, which 60: * ipc_kmsg_copyout_compat copies to msg_type. 61: */ 62: 63: #define NOTIFY_MSGH_SEQNO MSG_TYPE_EMERGENCY 1.1.1.2 ! root 64: #else /* MACH_IPC_COMPAT */ 1.1 root 65: #define NOTIFY_MSGH_SEQNO 0 1.1.1.2 ! root 66: #endif /* MACH_IPC_COMPAT */ 1.1 root 67: 68: /* 69: * Routine: ipc_notify_init_port_deleted 70: * Purpose: 71: * Initialize a template for port-deleted notifications. 72: */ 73: 74: void 75: ipc_notify_init_port_deleted(n) 76: mach_port_deleted_notification_t *n; 77: { 78: mach_msg_header_t *m = &n->not_header; 79: mach_msg_type_t *t = &n->not_type; 80: 81: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 82: m->msgh_size = sizeof *n; 83: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 84: m->msgh_local_port = MACH_PORT_NULL; 85: m->msgh_remote_port = MACH_PORT_NULL; 86: m->msgh_id = MACH_NOTIFY_PORT_DELETED; 87: 88: t->msgt_name = MACH_MSG_TYPE_PORT_NAME; 89: t->msgt_size = PORT_T_SIZE_IN_BITS; 90: t->msgt_number = 1; 91: t->msgt_inline = TRUE; 92: t->msgt_longform = FALSE; 93: t->msgt_deallocate = FALSE; 94: t->msgt_unused = 0; 95: 96: n->not_port = MACH_PORT_NULL; 97: } 98: 99: /* 100: * Routine: ipc_notify_init_msg_accepted 101: * Purpose: 102: * Initialize a template for msg-accepted notifications. 103: */ 104: 105: void 106: ipc_notify_init_msg_accepted(n) 107: mach_msg_accepted_notification_t *n; 108: { 109: mach_msg_header_t *m = &n->not_header; 110: mach_msg_type_t *t = &n->not_type; 111: 112: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 113: m->msgh_size = sizeof *n; 114: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 115: m->msgh_local_port = MACH_PORT_NULL; 116: m->msgh_remote_port = MACH_PORT_NULL; 117: m->msgh_id = MACH_NOTIFY_MSG_ACCEPTED; 118: 119: t->msgt_name = MACH_MSG_TYPE_PORT_NAME; 120: t->msgt_size = PORT_T_SIZE_IN_BITS; 121: t->msgt_number = 1; 122: t->msgt_inline = TRUE; 123: t->msgt_longform = FALSE; 124: t->msgt_deallocate = FALSE; 125: t->msgt_unused = 0; 126: 127: n->not_port = MACH_PORT_NULL; 128: } 129: 130: /* 131: * Routine: ipc_notify_init_port_destroyed 132: * Purpose: 133: * Initialize a template for port-destroyed notifications. 134: */ 135: 136: void 137: ipc_notify_init_port_destroyed( 138: mach_port_destroyed_notification_t *n) 139: { 140: mach_msg_header_t *m = &n->not_header; 141: mach_msg_type_t *t = &n->not_type; 142: 143: m->msgh_bits = MACH_MSGH_BITS_COMPLEX | 144: MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 145: m->msgh_size = sizeof *n; 146: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 147: m->msgh_local_port = MACH_PORT_NULL; 148: m->msgh_remote_port = MACH_PORT_NULL; 149: m->msgh_id = MACH_NOTIFY_PORT_DESTROYED; 150: 151: t->msgt_name = MACH_MSG_TYPE_PORT_RECEIVE; 152: t->msgt_size = PORT_T_SIZE_IN_BITS; 153: t->msgt_number = 1; 154: t->msgt_inline = TRUE; 155: t->msgt_longform = FALSE; 156: t->msgt_deallocate = FALSE; 157: t->msgt_unused = 0; 158: 159: n->not_port = MACH_PORT_NULL; 160: } 161: 162: /* 163: * Routine: ipc_notify_init_no_senders 164: * Purpose: 165: * Initialize a template for no-senders notifications. 166: */ 167: 168: void 169: ipc_notify_init_no_senders( 170: mach_no_senders_notification_t *n) 171: { 172: mach_msg_header_t *m = &n->not_header; 173: mach_msg_type_t *t = &n->not_type; 174: 175: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 176: m->msgh_size = sizeof *n; 177: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 178: m->msgh_local_port = MACH_PORT_NULL; 179: m->msgh_remote_port = MACH_PORT_NULL; 180: m->msgh_id = MACH_NOTIFY_NO_SENDERS; 181: 182: t->msgt_name = MACH_MSG_TYPE_INTEGER_32; 183: t->msgt_size = PORT_T_SIZE_IN_BITS; 184: t->msgt_number = 1; 185: t->msgt_inline = TRUE; 186: t->msgt_longform = FALSE; 187: t->msgt_deallocate = FALSE; 188: t->msgt_unused = 0; 189: 190: n->not_count = 0; 191: } 192: 193: /* 194: * Routine: ipc_notify_init_send_once 195: * Purpose: 196: * Initialize a template for send-once notifications. 197: */ 198: 199: void 200: ipc_notify_init_send_once( 201: mach_send_once_notification_t *n) 202: { 203: mach_msg_header_t *m = &n->not_header; 204: 205: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 206: m->msgh_size = sizeof *n; 207: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 208: m->msgh_local_port = MACH_PORT_NULL; 209: m->msgh_remote_port = MACH_PORT_NULL; 210: m->msgh_id = MACH_NOTIFY_SEND_ONCE; 211: } 212: 213: /* 214: * Routine: ipc_notify_init_dead_name 215: * Purpose: 216: * Initialize a template for dead-name notifications. 217: */ 218: 219: void 220: ipc_notify_init_dead_name( 221: mach_dead_name_notification_t *n) 222: { 223: mach_msg_header_t *m = &n->not_header; 224: mach_msg_type_t *t = &n->not_type; 225: 226: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); 227: m->msgh_size = sizeof *n; 228: m->msgh_seqno = NOTIFY_MSGH_SEQNO; 229: m->msgh_local_port = MACH_PORT_NULL; 230: m->msgh_remote_port = MACH_PORT_NULL; 231: m->msgh_id = MACH_NOTIFY_DEAD_NAME; 232: 233: t->msgt_name = MACH_MSG_TYPE_PORT_NAME; 234: t->msgt_size = PORT_T_SIZE_IN_BITS; 235: t->msgt_number = 1; 236: t->msgt_inline = TRUE; 237: t->msgt_longform = FALSE; 238: t->msgt_deallocate = FALSE; 239: t->msgt_unused = 0; 240: 241: n->not_port = MACH_PORT_NULL; 242: } 243: 244: /* 245: * Routine: ipc_notify_init 246: * Purpose: 247: * Initialize the notification subsystem. 248: */ 249: 250: void 251: ipc_notify_init(void) 252: { 253: ipc_notify_init_port_deleted(&ipc_notify_port_deleted_template); 254: ipc_notify_init_msg_accepted(&ipc_notify_msg_accepted_template); 255: ipc_notify_init_port_destroyed(&ipc_notify_port_destroyed_template); 256: ipc_notify_init_no_senders(&ipc_notify_no_senders_template); 257: ipc_notify_init_send_once(&ipc_notify_send_once_template); 258: ipc_notify_init_dead_name(&ipc_notify_dead_name_template); 259: } 260: 261: /* 262: * Routine: ipc_notify_port_deleted 263: * Purpose: 264: * Send a port-deleted notification. 265: * Conditions: 266: * Nothing locked. 267: * Consumes a ref/soright for port. 268: */ 269: 270: void 271: ipc_notify_port_deleted(port, name) 272: ipc_port_t port; 273: mach_port_t name; 274: { 275: ipc_kmsg_t kmsg; 276: mach_port_deleted_notification_t *n; 277: 278: kmsg = ikm_alloc(sizeof *n); 279: if (kmsg == IKM_NULL) { 280: printf("dropped port-deleted (0x%08x, 0x%x)\n", port, name); 281: ipc_port_release_sonce(port); 282: return; 283: } 284: 285: ikm_init(kmsg, sizeof *n); 286: n = (mach_port_deleted_notification_t *) &kmsg->ikm_header; 287: *n = ipc_notify_port_deleted_template; 288: 289: n->not_header.msgh_remote_port = (mach_port_t) port; 290: n->not_port = name; 291: 292: ipc_mqueue_send_always(kmsg); 293: } 294: 295: /* 296: * Routine: ipc_notify_msg_accepted 297: * Purpose: 298: * Send a msg-accepted notification. 299: * Conditions: 300: * Nothing locked. 301: * Consumes a ref/soright for port. 302: */ 303: 304: void 305: ipc_notify_msg_accepted(port, name) 306: ipc_port_t port; 307: mach_port_t name; 308: { 309: ipc_kmsg_t kmsg; 310: mach_msg_accepted_notification_t *n; 311: 312: kmsg = ikm_alloc(sizeof *n); 313: if (kmsg == IKM_NULL) { 314: printf("dropped msg-accepted (0x%08x, 0x%x)\n", port, name); 315: ipc_port_release_sonce(port); 316: return; 317: } 318: 319: ikm_init(kmsg, sizeof *n); 320: n = (mach_msg_accepted_notification_t *) &kmsg->ikm_header; 321: *n = ipc_notify_msg_accepted_template; 322: 323: n->not_header.msgh_remote_port = (mach_port_t) port; 324: n->not_port = name; 325: 326: ipc_mqueue_send_always(kmsg); 327: } 328: 329: /* 330: * Routine: ipc_notify_port_destroyed 331: * Purpose: 332: * Send a port-destroyed notification. 333: * Conditions: 334: * Nothing locked. 335: * Consumes a ref/soright for port. 336: * Consumes a ref for right, which should be a receive right 337: * prepped for placement into a message. (In-transit, 338: * or in-limbo if a circularity was detected.) 339: */ 340: 341: void 342: ipc_notify_port_destroyed(port, right) 343: ipc_port_t port; 344: ipc_port_t right; 345: { 346: ipc_kmsg_t kmsg; 347: mach_port_destroyed_notification_t *n; 348: 349: kmsg = ikm_alloc(sizeof *n); 350: if (kmsg == IKM_NULL) { 351: printf("dropped port-destroyed (0x%08x, 0x%08x)\n", 352: port, right); 353: ipc_port_release_sonce(port); 354: ipc_port_release_receive(right); 355: return; 356: } 357: 358: ikm_init(kmsg, sizeof *n); 359: n = (mach_port_destroyed_notification_t *) &kmsg->ikm_header; 360: *n = ipc_notify_port_destroyed_template; 361: 362: n->not_header.msgh_remote_port = (mach_port_t) port; 363: n->not_port = (mach_port_t) right; 364: 365: ipc_mqueue_send_always(kmsg); 366: } 367: 368: /* 369: * Routine: ipc_notify_no_senders 370: * Purpose: 371: * Send a no-senders notification. 372: * Conditions: 373: * Nothing locked. 374: * Consumes a ref/soright for port. 375: */ 376: 377: void 378: ipc_notify_no_senders(port, mscount) 379: ipc_port_t port; 380: mach_port_mscount_t mscount; 381: { 382: ipc_kmsg_t kmsg; 383: mach_no_senders_notification_t *n; 384: 385: #if NORMA_IPC 386: if (ip_nsproxyp(port)) { 387: assert(mscount == 0); 388: norma_ipc_notify_no_senders(ip_nsproxy(port)); 389: return; 390: } 1.1.1.2 ! root 391: #endif /* NORMA_IPC */ 1.1 root 392: kmsg = ikm_alloc(sizeof *n); 393: if (kmsg == IKM_NULL) { 394: printf("dropped no-senders (0x%08x, %u)\n", port, mscount); 395: ipc_port_release_sonce(port); 396: return; 397: } 398: 399: ikm_init(kmsg, sizeof *n); 400: n = (mach_no_senders_notification_t *) &kmsg->ikm_header; 401: *n = ipc_notify_no_senders_template; 402: 403: n->not_header.msgh_remote_port = (mach_port_t) port; 404: n->not_count = mscount; 405: 406: ipc_mqueue_send_always(kmsg); 407: } 408: 409: /* 410: * Routine: ipc_notify_send_once 411: * Purpose: 412: * Send a send-once notification. 413: * Conditions: 414: * Nothing locked. 415: * Consumes a ref/soright for port. 416: */ 417: 418: void 419: ipc_notify_send_once(port) 420: ipc_port_t port; 421: { 422: ipc_kmsg_t kmsg; 423: mach_send_once_notification_t *n; 424: 425: kmsg = ikm_alloc(sizeof *n); 426: if (kmsg == IKM_NULL) { 427: printf("dropped send-once (0x%08x)\n", port); 428: ipc_port_release_sonce(port); 429: return; 430: } 431: 432: ikm_init(kmsg, sizeof *n); 433: n = (mach_send_once_notification_t *) &kmsg->ikm_header; 434: *n = ipc_notify_send_once_template; 435: 436: n->not_header.msgh_remote_port = (mach_port_t) port; 437: 438: ipc_mqueue_send_always(kmsg); 439: } 440: 441: /* 442: * Routine: ipc_notify_dead_name 443: * Purpose: 444: * Send a dead-name notification. 445: * Conditions: 446: * Nothing locked. 447: * Consumes a ref/soright for port. 448: */ 449: 450: void 451: ipc_notify_dead_name(port, name) 452: ipc_port_t port; 453: mach_port_t name; 454: { 455: ipc_kmsg_t kmsg; 456: mach_dead_name_notification_t *n; 457: 458: kmsg = ikm_alloc(sizeof *n); 459: if (kmsg == IKM_NULL) { 460: printf("dropped dead-name (0x%08x, 0x%x)\n", port, name); 461: ipc_port_release_sonce(port); 462: return; 463: } 464: 465: ikm_init(kmsg, sizeof *n); 466: n = (mach_dead_name_notification_t *) &kmsg->ikm_header; 467: *n = ipc_notify_dead_name_template; 468: 469: n->not_header.msgh_remote_port = (mach_port_t) port; 470: n->not_port = name; 471: 472: ipc_mqueue_send_always(kmsg); 473: } 474: 475: #if MACH_IPC_COMPAT 476: 477: /* 478: * Routine: ipc_notify_port_deleted_compat 479: * Purpose: 480: * Send a port-deleted notification. 481: * Sends it to a send right instead of a send-once right. 482: * Conditions: 483: * Nothing locked. 484: * Consumes a ref/sright for port. 485: */ 486: 487: void 488: ipc_notify_port_deleted_compat(port, name) 489: ipc_port_t port; 490: mach_port_t name; 491: { 492: ipc_kmsg_t kmsg; 493: mach_port_deleted_notification_t *n; 494: 495: kmsg = ikm_alloc(sizeof *n); 496: if (kmsg == IKM_NULL) { 497: printf("dropped port-deleted-compat (0x%08x, 0x%x)\n", 498: port, name); 499: ipc_port_release_send(port); 500: return; 501: } 502: 503: ikm_init(kmsg, sizeof *n); 504: n = (mach_port_deleted_notification_t *) &kmsg->ikm_header; 505: *n = ipc_notify_port_deleted_template; 506: 507: n->not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); 508: n->not_header.msgh_remote_port = (mach_port_t) port; 509: n->not_port = name; 510: 511: ipc_mqueue_send_always(kmsg); 512: } 513: 514: /* 515: * Routine: ipc_notify_msg_accepted_compat 516: * Purpose: 517: * Send a msg-accepted notification. 518: * Sends it to a send right instead of a send-once right. 519: * Conditions: 520: * Nothing locked. 521: * Consumes a ref/sright for port. 522: */ 523: 524: void 525: ipc_notify_msg_accepted_compat(port, name) 526: ipc_port_t port; 527: mach_port_t name; 528: { 529: ipc_kmsg_t kmsg; 530: mach_msg_accepted_notification_t *n; 531: 532: kmsg = ikm_alloc(sizeof *n); 533: if (kmsg == IKM_NULL) { 534: printf("dropped msg-accepted-compat (0x%08x, 0x%x)\n", 535: port, name); 536: ipc_port_release_send(port); 537: return; 538: } 539: 540: ikm_init(kmsg, sizeof *n); 541: n = (mach_msg_accepted_notification_t *) &kmsg->ikm_header; 542: *n = ipc_notify_msg_accepted_template; 543: 544: n->not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); 545: n->not_header.msgh_remote_port = (mach_port_t) port; 546: n->not_port = name; 547: 548: ipc_mqueue_send_always(kmsg); 549: } 550: 551: /* 552: * Routine: ipc_notify_port_destroyed_compat 553: * Purpose: 554: * Send a port-destroyed notification. 555: * Sends it to a send right instead of a send-once right. 556: * Conditions: 557: * Nothing locked. 558: * Consumes a ref/sright for port. 559: * Consumes a ref for right, which should be a receive right 560: * prepped for placement into a message. (In-transit, 561: * or in-limbo if a circularity was detected.) 562: */ 563: 564: void 565: ipc_notify_port_destroyed_compat(port, right) 566: ipc_port_t port; 567: ipc_port_t right; 568: { 569: ipc_kmsg_t kmsg; 570: mach_port_destroyed_notification_t *n; 571: 572: kmsg = ikm_alloc(sizeof *n); 573: if (kmsg == IKM_NULL) { 574: printf("dropped port-destroyed-compat (0x%08x, 0x%08x)\n", 575: port, right); 576: ipc_port_release_send(port); 577: ipc_port_release_receive(right); 578: return; 579: } 580: 581: ikm_init(kmsg, sizeof *n); 582: n = (mach_port_destroyed_notification_t *) &kmsg->ikm_header; 583: *n = ipc_notify_port_destroyed_template; 584: 585: n->not_header.msgh_bits = MACH_MSGH_BITS_COMPLEX | 586: MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0); 587: n->not_header.msgh_remote_port = (mach_port_t) port; 588: n->not_port = (mach_port_t) right; 589: 590: ipc_mqueue_send_always(kmsg); 591: } 592: 1.1.1.2 ! root 593: #endif /* MACH_IPC_COMPAT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.