msg-destroy.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1991,1990 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  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.
  11. *
  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.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. /*
  27. * (pre-GNU) HISTORY
  28. *
  29. * Revision 2.4 91/05/14 17:53:15 mrt
  30. * Correcting copyright
  31. *
  32. * Revision 2.3 91/02/14 14:17:43 mrt
  33. * Added new Mach copyright
  34. * [91/02/13 12:44:15 mrt]
  35. *
  36. * Revision 2.2 90/08/06 17:24:22 rpd
  37. * Created.
  38. *
  39. */
  40. #include <libc-pointer-arith.h>
  41. #if 1
  42. #include <mach.h>
  43. #else
  44. /* This is what CMU did, but that fails to declare some used functions. */
  45. #include <mach/port.h>
  46. #include <mach/message.h>
  47. #include <mach_init.h>
  48. #endif
  49. static void mach_msg_destroy_port(mach_port_t, mach_msg_type_name_t);
  50. static void mach_msg_destroy_memory(vm_offset_t, vm_size_t);
  51. /*
  52. * Routine: mach_msg_destroy
  53. * Purpose:
  54. * Deallocates all port rights and out-of-line memory
  55. * found in a received message.
  56. */
  57. void
  58. __mach_msg_destroy (mach_msg_header_t *msg)
  59. {
  60. mach_msg_bits_t mbits = msg->msgh_bits;
  61. /*
  62. * The msgh_local_port field doesn't hold a port right.
  63. * The receive operation consumes the destination port right.
  64. */
  65. mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
  66. if (mbits & MACH_MSGH_BITS_COMPLEX) {
  67. vm_offset_t saddr;
  68. vm_offset_t eaddr;
  69. saddr = (vm_offset_t) (msg + 1);
  70. eaddr = (vm_offset_t) msg + msg->msgh_size;
  71. while (saddr < eaddr) {
  72. mach_msg_type_long_t *type;
  73. mach_msg_type_name_t name;
  74. mach_msg_type_size_t size;
  75. mach_msg_type_number_t number;
  76. boolean_t is_inline;
  77. vm_size_t length;
  78. vm_offset_t addr;
  79. type = (mach_msg_type_long_t *) saddr;
  80. is_inline = type->msgtl_header.msgt_inline;
  81. if (type->msgtl_header.msgt_longform) {
  82. name = type->msgtl_name;
  83. size = type->msgtl_size;
  84. number = type->msgtl_number;
  85. saddr += sizeof(mach_msg_type_long_t);
  86. } else {
  87. name = type->msgtl_header.msgt_name;
  88. size = type->msgtl_header.msgt_size;
  89. number = type->msgtl_header.msgt_number;
  90. saddr += sizeof(mach_msg_type_t);
  91. }
  92. /* Calculate length of data in bytes... */
  93. length = ((number * size) + 7) >> 3;
  94. /* ... and round up using uintptr_t alignment */
  95. length = ALIGN_UP (length, __alignof__ (uintptr_t));
  96. addr = is_inline ? saddr : * (vm_offset_t *) saddr;
  97. if (MACH_MSG_TYPE_PORT_ANY(name)) {
  98. mach_msg_type_number_t i;
  99. if (is_inline) {
  100. mach_port_name_inlined_t *inlined_ports = (mach_port_name_inlined_t *)addr;
  101. for (i = 0; i < number; i++)
  102. mach_msg_destroy_port(inlined_ports[i].name, name);
  103. } else {
  104. mach_port_t *ports = (mach_port_t *) addr;
  105. for (i = 0; i < number; i++)
  106. mach_msg_destroy_port(ports[i], name);
  107. }
  108. }
  109. if (is_inline) {
  110. saddr += length;
  111. } else {
  112. mach_msg_destroy_memory(addr, length);
  113. saddr += sizeof(vm_offset_t);
  114. }
  115. }
  116. }
  117. }
  118. weak_alias (__mach_msg_destroy, mach_msg_destroy)
  119. libc_hidden_def (__mach_msg_destroy)
  120. static void
  121. mach_msg_destroy_port (mach_port_t port, mach_msg_type_name_t type)
  122. {
  123. if (MACH_PORT_VALID(port)) switch (type) {
  124. case MACH_MSG_TYPE_MOVE_SEND:
  125. case MACH_MSG_TYPE_MOVE_SEND_ONCE:
  126. /* destroy the send/send-once right */
  127. (void) __mach_port_deallocate(mach_task_self(), port);
  128. break;
  129. case MACH_MSG_TYPE_MOVE_RECEIVE:
  130. /* destroy the receive right */
  131. (void) __mach_port_mod_refs(mach_task_self(), port,
  132. MACH_PORT_RIGHT_RECEIVE, -1);
  133. break;
  134. case MACH_MSG_TYPE_MAKE_SEND:
  135. /* create a send right and then destroy it */
  136. (void) __mach_port_insert_right(mach_task_self(), port,
  137. port, MACH_MSG_TYPE_MAKE_SEND);
  138. (void) __mach_port_deallocate(mach_task_self(), port);
  139. break;
  140. case MACH_MSG_TYPE_MAKE_SEND_ONCE:
  141. /* create a send-once right and then destroy it */
  142. (void) __mach_port_extract_right(mach_task_self(), port,
  143. MACH_MSG_TYPE_MAKE_SEND_ONCE,
  144. &port, &type);
  145. (void) __mach_port_deallocate(mach_task_self(), port);
  146. break;
  147. }
  148. }
  149. static void
  150. mach_msg_destroy_memory (vm_offset_t addr, vm_size_t size)
  151. {
  152. if (size > 0)
  153. (void) __vm_deallocate(__mach_task_self(), addr, size);
  154. }