|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1994 NeXT Computer, Inc.
27: *
28: * Random stuff needed for new IPC under NEXTSTEP.
29: *
30: * HISTORY
31: *
32: * 5 May 1994 ? at NeXT
33: * Created.
34: */
35:
36: #import <mach/features.h>
37:
38: #import <mach/mach_types.h>
39: #import <mach/notify.h>
40:
41: static inline
42: port_name_t
43: do_object_copyout(
44: task_t task,
45: ipc_port_t port
46: )
47: {
48: port_name_t name;
49:
50: if (port != IP_NULL) {
51: port = ipc_port_copy_send(port);
52: if (port != IP_DEAD)
53: ipc_object_copyout(
54: task->itk_space, port,
55: MACH_MSG_TYPE_PORT_SEND, TRUE, &name);
56: else
57: name = PORT_NULL;
58: }
59: else
60: name = PORT_NULL;
61:
62: return name;
63: }
64:
65: /*
66: * Why are the semantics of hostXXXself() and
67: * device_master_self() so inconsistent?
68: */
69:
70: port_name_t host_priv_self()
71: {
72: register task_t self = current_thread()->task;
73: register ipc_port_t port;
74: port_name_t name;
75:
76: if (!is_suser()) {
77: name = PORT_NULL;
78: }
79: else {
80: port = realhost.host_priv_self;
81: name = do_object_copyout(self, port);
82: }
83: return name;
84: }
85:
86: #if DRIVERKIT
87:
88: port_name_t device_master_self()
89: {
90: register task_t self = current_thread()->task;
91: register ipc_port_t port;
92: port_name_t name;
93:
94: if (!is_suser()) {
95: port = realhost.host_self;
96: }
97: else {
98: port = realhost.host_priv_self;
99: }
100: name = do_object_copyout(self, port);
101: return name;
102: }
103:
104: #endif DRIVERKIT
105:
106: /*
107: * This should be implemented using
108: * the name service (or object service).
109: */
110:
111: ipc_port_t lookupd_port, lookupd_port_priv;
112:
113: static
114: ipc_port_t
115: _lookupd_port_choose(void)
116: {
117: ipc_port_t port;
118:
119: if (lookupd_port_priv != IP_NULL && is_suser1())
120: port = lookupd_port_priv;
121: else
122: port = lookupd_port;
123:
124: return port;
125: }
126:
127: port_name_t
128: _lookupd_port(name)
129: port_name_t name;
130: {
131: register task_t self = current_thread()->task;
132: ipc_port_t port;
133:
134: if (name != PORT_NULL) {
135: if (!is_suser())
136: name = PORT_NULL;
137: else {
138: if (ipc_object_copyin(self->itk_space,
139: name, MACH_MSG_TYPE_MAKE_SEND,
140: &port) == KERN_SUCCESS) {
141: if (lookupd_port != IP_NULL)
142: ipc_port_release_send(lookupd_port);
143: lookupd_port = port;
144: }
145: else
146: name = PORT_NULL;
147: }
148: }
149: else {
150: port = _lookupd_port_choose();
151: name = do_object_copyout(self, port);
152: }
153: return name;
154: }
155:
156: port_name_t
157: _lookupd_port1(
158: port_name_t name)
159: {
160: register task_t self = current_thread()->task;
161: ipc_port_t port;
162:
163: if (!is_suser())
164: return (PORT_NULL);
165:
166: if (name != PORT_NULL) {
167: if (ipc_object_copyin(self->itk_space,
168: name, MACH_MSG_TYPE_MAKE_SEND,
169: &port) == KERN_SUCCESS) {
170: if (lookupd_port_priv != IP_NULL)
171: ipc_port_release_send(lookupd_port_priv);
172: lookupd_port_priv = port;
173: }
174: else
175: name = PORT_NULL;
176: }
177: else {
178: port = lookupd_port;
179: name = do_object_copyout(self, port);
180: }
181: return name;
182: }
183:
184: /*
185: * This should definitely be handled
186: * by the object service.
187: */
188:
189: ipc_port_t ev_port_list[2] = { IP_NULL, IP_NULL };
190:
191: port_name_t
192: _event_port_by_tag( num )
193: int num;
194: {
195: register task_t mytask = current_thread()->task;
196: register ipc_port_t port;
197: port_name_t name;
198:
199: if (num == 0 && !is_suser()) /* Security check on privileged port */
200: return PORT_NULL;
201: if ( num < 0 || num > (sizeof ev_port_list/sizeof ev_port_list[0]) )
202: return PORT_NULL;
203:
204: port = ev_port_list[num];
205:
206: name = do_object_copyout(mytask, port);
207: return name;
208: }
209:
210: boolean_t
211: object_copyin(
212: task_t task,
213: port_name_t name,
214: mach_msg_type_name_t rights,
215: boolean_t dealloc,
216: ipc_port_t *port
217: )
218: {
219: if (ipc_object_copyin_compat(
220: task->itk_space,
221: name, rights, dealloc,
222: port) != KERN_SUCCESS)
223: return FALSE;
224: else
225: return TRUE;
226: }
227:
228: void
229: object_copyout(
230: task_t task,
231: ipc_port_t port,
232: mach_msg_type_name_t rights,
233: port_name_t *namep
234: )
235: {
236: if (port == IP_NULL)
237: panic("object_copyout");
238:
239: if (rights == MSG_TYPE_PORT_ALL)
240: rights = MACH_MSG_TYPE_PORT_RECEIVE;
241: else
242: rights = MACH_MSG_TYPE_PORT_SEND;
243:
244: if (port == IP_NULL ||
245: ipc_object_copyout_compat(
246: task->itk_space,
247: port, rights,
248: namep) != KERN_SUCCESS)
249: *namep = PORT_NULL;
250: }
251:
252: void
253: port_reference(
254: ipc_port_t port
255: )
256: {
257: if (port != IP_NULL)
258: (void) ipc_port_copy_send(port); /* XXX */
259: }
260:
261: void
262: port_release(
263: ipc_port_t port
264: )
265: {
266: if (port != IP_NULL)
267: ipc_port_release_send(port); /* XXX */
268: }
269:
270: void
271: send_notification(task, msg_id, name)
272: register task_t task; /* Who we're notifying */
273: int msg_id; /* What event occurred */
274: port_name_t name; /* What port is involved */
275: {
276: ipc_port_t tnotify;
277:
278: if (msg_id != NOTIFY_MSG_ACCEPTED)
279: return;
280:
281: if (task_get_special_port(task,
282: TASK_NOTIFY_PORT, &tnotify) != KERN_SUCCESS)
283: return;
284:
285: ipc_notify_msg_accepted_compat(tnotify, name);
286: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.