1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41: #if 1
42: #include <mach.h>
43: #else
44:
45: #include <mach/port.h>
46: #include <mach/message.h>
47: #include <mach_init.h>
48: #endif
49:
50: static void mach_msg_destroy_port(mach_port_t, mach_msg_type_name_t);
51: static void mach_msg_destroy_memory(vm_offset_t, vm_size_t);
52:
53:
54:
55:
56:
57:
58:
59:
60: void
61: __mach_msg_destroy(msg)
62: mach_msg_header_t *msg;
63: {
64: mach_msg_bits_t mbits = msg->msgh_bits;
65:
66:
67:
68:
69:
70:
71: mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
72:
73: if (mbits & MACH_MSGH_BITS_COMPLEX) {
74: #ifdef MACH_MSG_PORT_DESCRIPTOR
75: mach_msg_body_t *body;
76: mach_msg_descriptor_t *saddr, *eaddr;
77:
78: body = (mach_msg_body_t *) (msg + 1);
79: saddr = (mach_msg_descriptor_t *)
80: ((mach_msg_base_t *) msg + 1);
81: eaddr = saddr + body->msgh_descriptor_count;
82:
83: for ( ; saddr < eaddr; saddr++) {
84: switch (saddr->type.type) {
85:
86: case MACH_MSG_PORT_DESCRIPTOR: {
87: mach_msg_port_descriptor_t *dsc;
88:
89:
90:
91:
92: dsc = &saddr->port;
93: mach_msg_destroy_port(dsc->name, dsc->disposition);
94: break;
95: }
96:
97: case MACH_MSG_OOL_DESCRIPTOR : {
98: mach_msg_ool_descriptor_t *dsc;
99:
100:
101:
102:
103: dsc = &saddr->out_of_line;
104: if (dsc->deallocate) {
105: mach_msg_destroy_memory((vm_offset_t)dsc->address,
106: dsc->size);
107: }
108: break;
109: }
110:
111: case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
112: mach_port_t *ports;
113: mach_msg_ool_ports_descriptor_t *dsc;
114: mach_msg_type_number_t j;
115:
116:
117:
118:
119: dsc = &saddr->ool_ports;
120: ports = (mach_port_t *) dsc->address;
121: for (j = 0; j < dsc->count; j++, ports++) {
122: mach_msg_destroy_port(*ports, dsc->disposition);
123: }
124:
125:
126:
127:
128: if (dsc->deallocate) {
129: mach_msg_destroy_memory((vm_offset_t)dsc->address,
130: dsc->count * sizeof(mach_port_t));
131: }
132: break;
133: }
134: }
135: }
136: #else
137: vm_offset_t saddr;
138: vm_offset_t eaddr;
139:
140: saddr = (vm_offset_t) (msg + 1);
141: eaddr = (vm_offset_t) msg + msg->msgh_size;
142:
143: while (saddr < eaddr) {
144: mach_msg_type_long_t *type;
145: mach_msg_type_name_t name;
146: mach_msg_type_size_t size;
147: mach_msg_type_number_t number;
148: boolean_t is_inline;
149: vm_size_t length;
150: vm_offset_t addr;
151:
152: type = (mach_msg_type_long_t *) saddr;
153: is_inline = type->msgtl_header.msgt_inline;
154: if (type->msgtl_header.msgt_longform) {
155: name = type->msgtl_name;
156: size = type->msgtl_size;
157: number = type->msgtl_number;
158: saddr += sizeof(mach_msg_type_long_t);
159: } else {
160: name = type->msgtl_header.msgt_name;
161: size = type->msgtl_header.msgt_size;
162: number = type->msgtl_header.msgt_number;
163: saddr += sizeof(mach_msg_type_t);
164: }
165:
166:
167: length = (((((number * size) + 7) >> 3) + sizeof (int) - 1)
168: &~ (sizeof (int) - 1));
169:
170: addr = is_inline ? saddr : * (vm_offset_t *) saddr;
171:
172: if (MACH_MSG_TYPE_PORT_ANY(name)) {
173: mach_port_t *ports = (mach_port_t *) addr;
174: mach_msg_type_number_t i;
175:
176: for (i = 0; i < number; i++)
177: mach_msg_destroy_port(*ports++, name);
178: }
179:
180: if (is_inline) {
181:
182: saddr += length;
183: } else {
184: mach_msg_destroy_memory(addr, length);
185: saddr += sizeof(vm_offset_t);
186: }
187: }
188: #endif
189: }
190: }
191:
192: weak_alias (__mach_msg_destroy, mach_msg_destroy)
193:
194: static void
195: mach_msg_destroy_port(port, type)
196: mach_port_t port;
197: mach_msg_type_name_t type;
198: {
199: if (MACH_PORT_VALID(port)) switch (type) {
200: case MACH_MSG_TYPE_MOVE_SEND:
201: case MACH_MSG_TYPE_MOVE_SEND_ONCE:
202:
203: (void) __mach_port_deallocate(mach_task_self(), port);
204: break;
205:
206: case MACH_MSG_TYPE_MOVE_RECEIVE:
207:
208: (void) __mach_port_mod_refs(mach_task_self(), port,
209: MACH_PORT_RIGHT_RECEIVE, -1);
210: break;
211:
212: case MACH_MSG_TYPE_MAKE_SEND:
213:
214: (void) __mach_port_insert_right(mach_task_self(), port,
215: port, MACH_MSG_TYPE_MAKE_SEND);
216: (void) __mach_port_deallocate(mach_task_self(), port);
217: break;
218:
219: case MACH_MSG_TYPE_MAKE_SEND_ONCE:
220:
221: (void) __mach_port_extract_right(mach_task_self(), port,
222: MACH_MSG_TYPE_MAKE_SEND_ONCE,
223: &port, &type);
224: (void) __mach_port_deallocate(mach_task_self(), port);
225: break;
226: }
227: }
228:
229: static void
230: mach_msg_destroy_memory(addr, size)
231: vm_offset_t addr;
232: vm_size_t size;
233: {
234: if (size > 0)
235: (void) __vm_deallocate(__mach_task_self(), addr, size);
236: }