]>
Commit | Line | Data |
---|---|---|
1815bff5 A |
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.0 (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 | * bootstrap -- fundamental service initiator and port server | |
26 | * Mike DeMoney, NeXT, Inc. | |
27 | * Copyright, 1990. All rights reserved. | |
28 | * | |
29 | * rpc_services.c -- implementation of bootstrap rpc services | |
30 | */ | |
31 | ||
32 | #import <mach/mach.h> | |
33 | #import <string.h> | |
34 | ||
35 | #import "bootstrap_internal.h" | |
36 | #import "error_log.h" | |
37 | #import "lists.h" | |
38 | #import "bootstrap.h" | |
39 | ||
40 | #ifndef ASSERT | |
41 | #define ASSERT(p) | |
42 | #endif | |
43 | ||
44 | #ifndef NULL | |
45 | #define NULL ((void *)0) | |
46 | #endif NULL | |
47 | ||
48 | /* extern port_all_t backup_port; */ | |
49 | ||
50 | /* | |
51 | * kern_return_t | |
52 | * bootstrap_check_in(mach_port_t bootstrap_port, | |
53 | * name_t service_name, | |
54 | * mach_port_t *service_portp) | |
55 | * | |
56 | * Returns receive rights to service_port of service named by service_name. | |
57 | * | |
58 | * Errors: Returns appropriate kernel errors on rpc failure. | |
59 | * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. | |
60 | * Returns BOOTSTRAP_SERVICE_NOT_DECLARED, if service not declared | |
61 | * in /etc/bootstrap.conf. | |
62 | * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been | |
63 | * registered or checked-in. | |
64 | */ | |
65 | kern_return_t | |
66 | x_bootstrap_check_in( | |
67 | mach_port_t bootstrap_port, | |
68 | name_t service_name, | |
69 | mach_port_t *service_portp) | |
70 | { | |
71 | kern_return_t result; | |
72 | service_t *servicep; | |
73 | server_t *serverp; | |
74 | bootstrap_info_t *bootstrap; | |
75 | ||
76 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
77 | serverp = lookup_server_by_port(bootstrap_port); | |
78 | if (serverp == NULL) { | |
79 | debug("bootstrap_check_in service %s has no server", | |
80 | service_name); | |
81 | return BOOTSTRAP_NOT_PRIVILEGED; | |
82 | } | |
83 | servicep = lookup_service_by_name(bootstrap, service_name); | |
84 | if (servicep == NULL || servicep->port == MACH_PORT_NULL) { | |
85 | debug("bootstrap_check_in service %s unknown%s", service_name, | |
86 | forward_ok ? " forwarding" : ""); | |
87 | result = BOOTSTRAP_UNKNOWN_SERVICE; | |
88 | goto forward; | |
89 | } | |
90 | if (servicep->server != NULL && servicep->server != serverp) { | |
91 | debug("bootstrap_check_in service %s not privileged", | |
92 | service_name); | |
93 | return BOOTSTRAP_NOT_PRIVILEGED; | |
94 | } | |
95 | if (servicep->servicetype == SELF || !canReceive(servicep->port)) { | |
96 | ASSERT(servicep->isActive); | |
97 | debug("bootstrap_check_in service %s already active", | |
98 | service_name); | |
99 | return BOOTSTRAP_SERVICE_ACTIVE; | |
100 | } | |
101 | log("Checkin service %s", service_name); | |
102 | ASSERT(servicep->isActive == FALSE); | |
103 | servicep->isActive = TRUE; | |
104 | *service_portp = servicep->port; | |
105 | info("Check-in port %d for service %s\n", | |
106 | servicep->port, servicep->name); | |
107 | return BOOTSTRAP_SUCCESS; | |
108 | forward: | |
109 | return forward_ok | |
110 | ? bootstrap_check_in(inherited_bootstrap_port, | |
111 | service_name, | |
112 | service_portp) | |
113 | : result; | |
114 | } | |
115 | ||
116 | /* | |
117 | * kern_return_t | |
118 | * bootstrap_register(mach_port_t bootstrap_port, | |
119 | * name_t service_name, | |
120 | * mach_port_t service_port) | |
121 | * | |
122 | * Registers send rights for the port service_port for the service named by | |
123 | * service_name. Registering a declared service or registering a service for | |
124 | * which bootstrap has receive rights via a port backup notification is | |
125 | * allowed. | |
126 | * The previous service port will be deallocated. Restarting services wishing | |
127 | * to resume service for previous clients must first attempt to checkin to the | |
128 | * service. | |
129 | * | |
130 | * Errors: Returns appropriate kernel errors on rpc failure. | |
131 | * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to | |
132 | * unprivileged bootstrap port. | |
133 | * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been | |
134 | * register or checked-in. | |
135 | */ | |
136 | kern_return_t | |
137 | x_bootstrap_register( | |
138 | mach_port_t bootstrap_port, | |
139 | name_t service_name, | |
140 | mach_port_t service_port) | |
141 | { | |
142 | service_t *servicep; | |
143 | server_t *serverp; | |
144 | bootstrap_info_t *bootstrap; | |
145 | mach_port_t old_port; | |
146 | ||
147 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
148 | ASSERT(canSend(service_port)); | |
149 | debug("Register attempt for service %s port %d", | |
150 | service_name, service_port); | |
151 | ||
152 | /* | |
153 | * If this bootstrap port is for a server, or it's an unprivileged | |
154 | * bootstrap can't register the port. | |
155 | */ | |
156 | serverp = lookup_server_by_port(bootstrap_port); | |
157 | servicep = lookup_service_by_name(bootstrap, service_name); | |
158 | if (servicep && servicep->server && servicep->server != serverp) | |
159 | return BOOTSTRAP_NOT_PRIVILEGED; | |
160 | ||
161 | if (serverp) | |
162 | bootstrap_port = bootstrap->bootstrap_port; | |
163 | else if (bootstrap_port != bootstrap->bootstrap_port) | |
164 | return BOOTSTRAP_NOT_PRIVILEGED; | |
165 | ||
166 | if (servicep == NULL || servicep->bootstrap != bootstrap) { | |
167 | servicep = new_service(bootstrap, | |
168 | service_name, | |
169 | service_port, | |
170 | ACTIVE, | |
171 | REGISTERED, | |
172 | NULL_SERVER); | |
173 | debug("Registered new service %s", service_name); | |
174 | } else { | |
175 | if (servicep->isActive) { | |
176 | debug("Register: service %s already active, port %d", | |
177 | servicep->name, servicep->port); | |
178 | ASSERT(!canReceive(servicep->port)); | |
179 | return BOOTSTRAP_SERVICE_ACTIVE; | |
180 | } | |
181 | old_port = servicep->port; | |
182 | servicep->port = service_port; | |
183 | msg_destroy_port(old_port); | |
184 | servicep->isActive = TRUE; | |
185 | log("Re-registered inactive service %s", service_name); | |
186 | } | |
187 | debug("Registering port %d for service %s\n", | |
188 | servicep->port, | |
189 | servicep->name); | |
190 | return BOOTSTRAP_SUCCESS; | |
191 | } | |
192 | ||
193 | /* | |
194 | * kern_return_t | |
195 | * bootstrap_look_up(mach_port_t bootstrap_port, | |
196 | * name_t service_name, | |
197 | * mach_port_t *service_portp) | |
198 | * | |
199 | * Returns send rights for the service port of the service named by | |
200 | * service_name in *service_portp. Service is not guaranteed to be active. | |
201 | * | |
202 | * Errors: Returns appropriate kernel errors on rpc failure. | |
203 | * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. | |
204 | */ | |
205 | kern_return_t | |
206 | x_bootstrap_look_up( | |
207 | mach_port_t bootstrap_port, | |
208 | name_t service_name, | |
209 | mach_port_t *service_portp) | |
210 | { | |
211 | service_t *servicep; | |
212 | bootstrap_info_t *bootstrap; | |
213 | ||
214 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
215 | servicep = lookup_service_by_name(bootstrap, service_name); | |
216 | if (servicep == NULL || servicep->port == MACH_PORT_NULL) { | |
217 | if (forward_ok) { | |
218 | #if DEBUG | |
219 | debug("bootstrap_look_up service %s forwarding", | |
220 | service_name); | |
221 | #endif DEBUG | |
222 | return bootstrap_look_up(inherited_bootstrap_port, | |
223 | service_name, | |
224 | service_portp); | |
225 | } else { | |
226 | #if DEBUG | |
227 | debug("bootstrap_look_up service %s unknown", | |
228 | service_name); | |
229 | #endif DEBUG | |
230 | return BOOTSTRAP_UNKNOWN_SERVICE; | |
231 | } | |
232 | } | |
233 | if (!canSend(servicep->port)) { | |
234 | error("Mysterious loss of send rights on port %d, " | |
235 | "deleting service %s", | |
236 | servicep->port, | |
237 | servicep->name); | |
238 | delete_service(servicep); | |
239 | return BOOTSTRAP_UNKNOWN_SERVICE; | |
240 | } | |
241 | *service_portp = servicep->port; | |
242 | #if DEBUG | |
243 | debug("Lookup returns port %d for service %s\n", | |
244 | servicep->port, | |
245 | servicep->name); | |
246 | #endif DEBUG | |
247 | return BOOTSTRAP_SUCCESS; | |
248 | } | |
249 | ||
250 | /* | |
251 | * kern_return_t | |
252 | * bootstrap_look_up_array(mach_port_t bootstrap_port, | |
253 | * name_array_t service_names, | |
254 | * int service_names_cnt, | |
255 | * mach_port_array_t *service_ports, | |
256 | * int *service_ports_cnt, | |
257 | * boolean_t *all_services_known) | |
258 | * | |
259 | * Returns port send rights in corresponding entries of the array service_ports | |
260 | * for all services named in the array service_names. Service_ports_cnt is | |
261 | * returned and will always equal service_names_cnt (assuming service_names_cnt | |
262 | * is greater than or equal to zero). | |
263 | * | |
264 | * Errors: Returns appropriate kernel errors on rpc failure. | |
265 | * Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory | |
266 | * for response. | |
267 | * Unknown service names have the corresponding service | |
268 | * port set to MACH_PORT_NULL. | |
269 | * If all services are known, all_services_known is true on | |
270 | * return, | |
271 | * if any service is unknown, it's false. | |
272 | */ | |
273 | kern_return_t | |
274 | x_bootstrap_look_up_array( | |
275 | mach_port_t bootstrap_port, | |
276 | name_array_t service_names, | |
277 | unsigned int service_names_cnt, | |
278 | mach_port_array_t *service_portsp, | |
279 | unsigned int *service_ports_cnt, | |
280 | boolean_t *all_services_known) | |
281 | { | |
282 | unsigned int i; | |
283 | static mach_port_t service_ports[BOOTSTRAP_MAX_LOOKUP_COUNT]; | |
284 | ||
285 | if (service_names_cnt > BOOTSTRAP_MAX_LOOKUP_COUNT) | |
286 | return BOOTSTRAP_BAD_COUNT; | |
287 | *service_ports_cnt = service_names_cnt; | |
288 | *all_services_known = TRUE; | |
289 | for (i = 0; i < service_names_cnt; i++) { | |
290 | if ( x_bootstrap_look_up(bootstrap_port, | |
291 | service_names[i], | |
292 | &service_ports[i]) | |
293 | != BOOTSTRAP_SUCCESS) | |
294 | { | |
295 | *all_services_known = FALSE; | |
296 | service_ports[i] = MACH_PORT_NULL; | |
297 | } | |
298 | } | |
299 | #if DEBUG | |
300 | debug("bootstrap_look_up_array returns %d ports", service_names_cnt); | |
301 | #endif DEBUG | |
302 | *service_portsp = service_ports; | |
303 | return BOOTSTRAP_SUCCESS; | |
304 | } | |
305 | ||
306 | /* | |
307 | * kern_return_t | |
308 | * bootstrap_status(mach_port_t bootstrap_port, | |
309 | * name_t service_name, | |
310 | * boolean_t *service_active); | |
311 | * | |
312 | * Returns: service_active is true if service is available. | |
313 | * | |
314 | * Errors: Returns appropriate kernel errors on rpc failure. | |
315 | * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. | |
316 | */ | |
317 | kern_return_t | |
318 | x_bootstrap_status( | |
319 | mach_port_t bootstrap_port, | |
320 | name_t service_name, | |
321 | boolean_t *service_active) | |
322 | { | |
323 | service_t *servicep; | |
324 | bootstrap_info_t *bootstrap; | |
325 | ||
326 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
327 | servicep = lookup_service_by_name(bootstrap, service_name); | |
328 | if (servicep == NULL) { | |
329 | if (forward_ok) { | |
330 | debug("bootstrap_status forwarding status, server %s", | |
331 | service_name); | |
332 | return bootstrap_status(inherited_bootstrap_port, | |
333 | service_name, | |
334 | service_active); | |
335 | } else { | |
336 | #if DEBUG | |
337 | debug("bootstrap_status service %s unknown", | |
338 | service_name); | |
339 | #endif DEBUG | |
340 | return BOOTSTRAP_UNKNOWN_SERVICE; | |
341 | } | |
342 | } | |
343 | *service_active = servicep->isActive; | |
344 | #if DEBUG | |
345 | debug("bootstrap_status server %s %sactive", service_name, | |
346 | servicep->isActive ? "" : "in"); | |
347 | #endif DEBUG | |
348 | return BOOTSTRAP_SUCCESS; | |
349 | } | |
350 | ||
351 | /* | |
352 | * kern_return_t | |
353 | * bootstrap_info(mach_port_t bootstrap_port, | |
354 | * name_array_t *service_names, | |
355 | * int *service_names_cnt, | |
356 | * name_array_t *server_names, | |
357 | * int *server_names_cnt, | |
358 | * bool_array_t *service_actives, | |
359 | * int *service_active_cnt); | |
360 | * | |
361 | * Returns bootstrap status for all known services. | |
362 | * | |
363 | * Errors: Returns appropriate kernel errors on rpc failure. | |
364 | */ | |
365 | kern_return_t | |
366 | x_bootstrap_info( | |
367 | mach_port_t bootstrap_port, | |
368 | name_array_t *service_namesp, | |
369 | unsigned int *service_names_cnt, | |
370 | name_array_t *server_namesp, | |
371 | unsigned int *server_names_cnt, | |
372 | bool_array_t *service_activesp, | |
373 | unsigned int *service_actives_cnt) | |
374 | { | |
375 | kern_return_t result; | |
376 | unsigned int i, cnt; | |
377 | service_t *servicep; | |
378 | server_t *serverp; | |
379 | bootstrap_info_t *bootstrap; | |
380 | name_array_t service_names; | |
381 | name_array_t server_names; | |
382 | bool_array_t service_actives; | |
383 | ||
384 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
385 | ||
386 | for ( cnt = i = 0, servicep = services.next | |
387 | ; i < nservices | |
388 | ; servicep = servicep->next, i++) | |
389 | { | |
390 | if (lookup_service_by_name(bootstrap, servicep->name) == servicep) | |
391 | { | |
392 | cnt++; | |
393 | } | |
394 | } | |
395 | result = vm_allocate(mach_task_self(), | |
396 | (vm_address_t *)&service_names, | |
397 | cnt * sizeof(service_names[0]), | |
398 | ANYWHERE); | |
399 | if (result != KERN_SUCCESS) | |
400 | return BOOTSTRAP_NO_MEMORY; | |
401 | ||
402 | result = vm_allocate(mach_task_self(), | |
403 | (vm_address_t *)&server_names, | |
404 | cnt * sizeof(server_names[0]), | |
405 | ANYWHERE); | |
406 | if (result != KERN_SUCCESS) { | |
407 | (void)vm_deallocate(mach_task_self(), | |
408 | (vm_address_t)service_names, | |
409 | cnt * sizeof(service_names[0])); | |
410 | return BOOTSTRAP_NO_MEMORY; | |
411 | } | |
412 | result = vm_allocate(mach_task_self(), | |
413 | (vm_address_t *)&service_actives, | |
414 | cnt * sizeof(service_actives[0]), | |
415 | ANYWHERE); | |
416 | if (result != KERN_SUCCESS) { | |
417 | (void)vm_deallocate(mach_task_self(), | |
418 | (vm_address_t)service_names, | |
419 | cnt * sizeof(service_names[0])); | |
420 | (void)vm_deallocate(mach_task_self(), | |
421 | (vm_address_t)server_names, | |
422 | cnt * sizeof(server_names[0])); | |
423 | return BOOTSTRAP_NO_MEMORY; | |
424 | } | |
425 | ||
426 | for ( i = 0, servicep = services.next | |
427 | ; i < nservices | |
428 | ; servicep = servicep->next) | |
429 | { | |
430 | if ( lookup_service_by_name(bootstrap, servicep->name) | |
431 | != servicep) | |
432 | continue; | |
433 | strncpy(service_names[i], | |
434 | servicep->name, | |
435 | sizeof(service_names[0])); | |
436 | service_names[i][sizeof(service_names[0]) - 1] = '\0'; | |
437 | if (servicep->server) { | |
438 | serverp = servicep->server; | |
439 | strncpy(server_names[i], | |
440 | serverp->cmd, | |
441 | sizeof(server_names[0])); | |
442 | server_names[i][sizeof(server_names[0]) - 1] = '\0'; | |
443 | debug("bootstrap info service %s server %s %sactive", | |
444 | servicep->name, | |
445 | serverp->cmd, servicep->isActive ? "" : "in"); | |
446 | } else { | |
447 | server_names[i][0] = '\0'; | |
448 | debug("bootstrap info service %s %sactive", | |
449 | servicep->name, servicep->isActive ? "" : "in"); | |
450 | } | |
451 | service_actives[i] = servicep->isActive; | |
452 | i++; | |
453 | } | |
454 | *service_namesp = service_names; | |
455 | *server_namesp = server_names; | |
456 | *service_activesp = service_actives; | |
457 | *service_names_cnt = *server_names_cnt = | |
458 | *service_actives_cnt = cnt; | |
459 | ||
460 | return BOOTSTRAP_SUCCESS; | |
461 | } | |
462 | ||
463 | /* | |
464 | * kern_return_t | |
465 | * bootstrap_subset(mach_port_t bootstrap_port, | |
466 | * mach_port_t requestor_port, | |
467 | * mach_port_t *subset_port); | |
468 | * | |
469 | * Returns a new port to use as a bootstrap port. This port behaves | |
470 | * exactly like the previous bootstrap_port, except that ports dynamically | |
471 | * registered via bootstrap_register() are available only to users of this | |
472 | * specific subset_port. Lookups on the subset_port will return ports | |
473 | * registered with this port specifically, and ports registered with | |
474 | * ancestors of this subset_port. Duplications of services already | |
475 | * registered with an ancestor port may be registered with the subset port | |
476 | * are allowed. Services already advertised may then be effectively removed | |
477 | * by registering MACH_PORT_NULL for the service. | |
478 | * When it is detected that the requestor_port is destroied the subset | |
479 | * port and all services advertized by it are destroied as well. | |
480 | * | |
481 | * Errors: Returns appropriate kernel errors on rpc failure. | |
482 | */ | |
483 | kern_return_t | |
484 | x_bootstrap_subset( | |
485 | mach_port_t bootstrap_port, | |
486 | mach_port_t requestor_port, | |
487 | mach_port_t *subset_port) | |
488 | { | |
489 | kern_return_t result; | |
490 | bootstrap_info_t *bootstrap; | |
491 | bootstrap_info_t *subset; | |
492 | mach_port_t new_bootstrap_port; | |
493 | ||
494 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
495 | ||
496 | result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &new_bootstrap_port); | |
497 | if (result != KERN_SUCCESS) | |
498 | kern_fatal(result, "mach_port_allocate"); | |
499 | result = mach_port_insert_right(mach_task_self(), new_bootstrap_port, new_bootstrap_port, MACH_MSG_TYPE_MAKE_SEND); | |
500 | if (result != KERN_SUCCESS) | |
501 | kern_fatal(result, "failed to insert send right"); | |
502 | ||
503 | result = mach_port_move_member(mach_task_self(), new_bootstrap_port, bootstrap_port_set); | |
504 | if (result != KERN_SUCCESS) | |
505 | kern_fatal(result, "port_set_add"); | |
506 | ||
507 | subset = new_bootstrap(bootstrap, new_bootstrap_port, requestor_port); | |
508 | *subset_port = new_bootstrap_port; | |
509 | debug("bootstrap_subset new bootstrap %d", new_bootstrap_port); | |
510 | return BOOTSTRAP_SUCCESS; | |
511 | } | |
512 | ||
513 | /* | |
514 | * kern_return_t | |
515 | * bootstrap_create_service(mach_port_t bootstrap_port, | |
516 | * name_t service_name, | |
517 | * mach_port_t *service_port) | |
518 | * | |
519 | * Creates a service named "service_name" and returns send rights to that | |
520 | * port in "service_port." The port may later be checked in as if this | |
521 | * port were configured in the bootstrap configuration file. | |
522 | * | |
523 | * Errors: Returns appropriate kernel errors on rpc failure. | |
524 | * Returns BOOTSTRAP_NAME_IN_USE, if service already exists. | |
525 | */ | |
526 | kern_return_t | |
527 | x_bootstrap_create_service( | |
528 | mach_port_t bootstrap_port, | |
529 | name_t service_name, | |
530 | mach_port_t *service_port) | |
531 | { | |
532 | service_t *servicep; | |
533 | bootstrap_info_t *bootstrap; | |
534 | kern_return_t result; | |
535 | mach_port_t previous; | |
536 | ||
537 | bootstrap = lookup_bootstrap_by_port(bootstrap_port); | |
538 | ASSERT(bootstrap); | |
539 | debug("Service creation attempt for service %s", service_name); | |
540 | ||
541 | servicep = lookup_service_by_name(bootstrap, service_name); | |
542 | if (servicep) { | |
543 | debug("Service creation attempt for service %s failed, " | |
544 | "service already exists", service_name); | |
545 | return BOOTSTRAP_NAME_IN_USE; | |
546 | } | |
547 | ||
548 | result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, service_port); | |
549 | if (result != KERN_SUCCESS) | |
550 | kern_fatal(result, "port_allocate"); | |
551 | result = mach_port_insert_right(mach_task_self(), *service_port, *service_port, MACH_MSG_TYPE_MAKE_SEND); | |
552 | if (result != KERN_SUCCESS) | |
553 | kern_fatal(result, "failed to insert send right"); | |
554 | #if notyet | |
555 | result = port_set_backup(mach_task_self(), *service_port, backup_port, | |
556 | &previous); | |
557 | if (result != KERN_SUCCESS) | |
558 | kern_fatal(result, "port_set_backup"); | |
559 | info("Declared port %d for service %s", *service_port, | |
560 | service_name); | |
561 | #endif /*notyet */ | |
562 | ||
563 | servicep = new_service(bootstrap, | |
564 | service_name, | |
565 | *service_port, | |
566 | !ACTIVE, | |
567 | DECLARED, | |
568 | NULL_SERVER); | |
569 | ||
570 | log("Created new service %s", service_name); | |
571 | ||
572 | return BOOTSTRAP_SUCCESS; | |
573 | } |