Mon Aug 14 16:51:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
[glibc.git] / sysdeps / mach / hurd / fork.c
blobb8b15743cd8ded8540dfdbb8c0ff76853981c9ac
1 /* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
19 #include <errno.h>
20 #include <unistd.h>
21 #include <hurd.h>
22 #include <hurd/signal.h>
23 #include <setjmp.h>
24 #include "thread_state.h"
25 #include <sysdep.h> /* For stack growth direction. */
26 #include "set-hooks.h"
27 #include <assert.h>
28 #include "hurdmalloc.h" /* XXX */
31 /* Things that want to be locked while forking. */
32 struct
34 size_t n;
35 struct mutex *locks[0];
36 } _hurd_fork_locks;
39 /* Things that want to be called before we fork, to prepare the parent for
40 task_create, when the new child task will inherit our address space. */
41 DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
43 /* Things that want to be called when we are forking, with the above all
44 locked. They are passed the task port of the child. The child process
45 is all set up except for doing proc_child, and has no threads yet. */
46 DEFINE_HOOK (_hurd_fork_setup_hook, (void));
48 /* Things to be run in the child fork. */
49 DEFINE_HOOK (_hurd_fork_child_hook, (void));
51 /* Things to be run in the parent fork. */
52 DEFINE_HOOK (_hurd_fork_parent_hook, (void));
55 /* Clone the calling process, creating an exact copy.
56 Return -1 for errors, 0 to the new process,
57 and the process ID of the new process to the old process. */
58 pid_t
59 __fork (void)
61 jmp_buf env;
62 pid_t pid;
63 size_t i;
64 error_t err;
65 thread_t thread_self = __mach_thread_self ();
66 struct hurd_sigstate *volatile ss;
68 ss = _hurd_self_sigstate ();
69 __spin_lock (&ss->lock);
70 ss->critical_section = 1;
71 __spin_unlock (&ss->lock);
73 #undef LOSE
74 #define LOSE assert_perror (err) /* XXX */
76 if (! setjmp (env))
78 process_t newproc;
79 task_t newtask;
80 thread_t thread, sigthread;
81 mach_port_urefs_t thread_refs, sigthread_refs;
82 struct machine_thread_state state;
83 mach_msg_type_number_t statecount;
84 mach_port_t *portnames = NULL;
85 mach_msg_type_number_t nportnames = 0;
86 mach_port_type_t *porttypes = NULL;
87 mach_msg_type_number_t nporttypes = 0;
88 thread_t *threads = NULL;
89 mach_msg_type_number_t nthreads = 0;
90 int ports_locked = 0;
92 /* Run things that prepare for forking before we create the task. */
93 RUN_HOOK (_hurd_fork_prepare_hook, ());
95 /* Lock things that want to be locked before we fork. */
96 for (i = 0; i < _hurd_fork_locks.n; ++i)
97 __mutex_lock (_hurd_fork_locks.locks[i]);
98 __mutex_lock (&_hurd_siglock);
100 newtask = MACH_PORT_NULL;
101 thread = sigthread = MACH_PORT_NULL;
102 newproc = MACH_PORT_NULL;
104 /* Lock all the port cells for the standard ports while we copy the
105 address space. We want to insert all the send rights into the
106 child with the same names. */
107 for (i = 0; i < _hurd_nports; ++i)
108 __spin_lock (&_hurd_ports[i].lock);
109 ports_locked = 1;
111 /* Create the child task. It will inherit a copy of our memory. */
112 err = __task_create (__mach_task_self (), 1, &newtask);
114 /* Unlock the global signal state lock, so we do not
115 block the signal thread any longer than necessary. */
116 __mutex_unlock (&_hurd_siglock);
118 if (err)
119 LOSE;
121 /* Fetch the names of all ports used in this task. */
122 if (err = __mach_port_names (__mach_task_self (),
123 &portnames, &nportnames,
124 &porttypes, &nporttypes))
125 LOSE;
126 if (nportnames != nporttypes)
128 err = EGRATUITOUS;
129 LOSE;
132 /* Get send rights for all the threads in this task.
133 We want to avoid giving these rights to the child. */
134 if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
135 LOSE;
137 /* Get the child process's proc server port. We will insert it into
138 the child with the same name as we use for our own proc server
139 port; and we will need it to set the child's message port. */
140 if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
141 newtask, &newproc))
142 LOSE;
144 /* Insert all our port rights into the child task. */
145 thread_refs = sigthread_refs = 0;
146 for (i = 0; i < nportnames; ++i)
148 if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
150 /* This is a receive right. We want to give the child task
151 its own new receive right under the same name. */
152 err = __mach_port_allocate_name (newtask,
153 MACH_PORT_RIGHT_RECEIVE,
154 portnames[i]);
155 if (err == KERN_NAME_EXISTS)
157 /* It already has a right under this name (?!). Well,
158 there is this bizarre old Mach IPC feature (in #ifdef
159 MACH_IPC_COMPAT in the ukernel) which results in new
160 tasks getting a new receive right for task special
161 port number 2. What else might be going on I'm not
162 sure. So let's check. */
163 #if !MACH_IPC_COMPAT
164 #define TASK_NOTIFY_PORT 2
165 #endif
166 assert (({ mach_port_t thisport, notify_port;
167 mach_msg_type_name_t poly;
168 (__task_get_special_port (newtask,
169 TASK_NOTIFY_PORT,
170 &notify_port) == 0 &&
171 __mach_port_extract_right
172 (newtask,
173 portnames[i],
174 MACH_MSG_TYPE_MAKE_SEND,
175 &thisport, &poly) == 0 &&
176 (thisport == notify_port) &&
177 __mach_port_deallocate (__mach_task_self (),
178 thisport) == 0 &&
179 __mach_port_deallocate (__mach_task_self (),
180 notify_port) == 0);
181 }));
183 else if (err)
184 LOSE;
185 if (porttypes[i] & MACH_PORT_TYPE_SEND)
187 /* Give the child as many send rights for its receive
188 right as we have for ours. */
189 mach_port_urefs_t refs;
190 mach_port_t port;
191 mach_msg_type_name_t poly;
192 if (err = __mach_port_get_refs (__mach_task_self (),
193 portnames[i],
194 MACH_PORT_RIGHT_SEND,
195 &refs))
196 LOSE;
197 if (err = __mach_port_extract_right (newtask,
198 portnames[i],
199 MACH_MSG_TYPE_MAKE_SEND,
200 &port, &poly))
201 LOSE;
202 if (portnames[i] == _hurd_msgport)
204 /* We just created a receive right for the child's
205 message port and are about to insert send rights
206 for it. Now, while we happen to have a send right
207 for it, give it to the proc server. */
208 mach_port_t old;
209 if (err = __proc_setmsgport (newproc, port, &old))
210 LOSE;
211 if (old != MACH_PORT_NULL)
212 /* XXX what to do here? */
213 __mach_port_deallocate (__mach_task_self (), old);
215 if (err = __mach_port_insert_right (newtask,
216 portnames[i],
217 port,
218 MACH_MSG_TYPE_MOVE_SEND))
219 LOSE;
220 if (refs > 1 &&
221 (err = __mach_port_mod_refs (newtask,
222 portnames[i],
223 MACH_PORT_RIGHT_SEND,
224 refs - 1)))
225 LOSE;
227 if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
229 /* Give the child a send-once right for its receive right,
230 since we have one for ours. */
231 mach_port_t port;
232 mach_msg_type_name_t poly;
233 if (err = __mach_port_extract_right
234 (newtask,
235 portnames[i],
236 MACH_MSG_TYPE_MAKE_SEND_ONCE,
237 &port, &poly))
238 LOSE;
239 if (err = __mach_port_insert_right
240 (newtask,
241 portnames[i], port,
242 MACH_MSG_TYPE_MOVE_SEND_ONCE))
243 LOSE;
246 else if (porttypes[i] &
247 (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
249 /* This is a send right or a dead name.
250 Give the child as many references for it as we have. */
251 mach_port_urefs_t refs, *record_refs = NULL;
252 mach_port_t insert;
253 if (portnames[i] == newtask)
254 /* Skip the name we use for the child's task port. */
255 continue;
256 if (portnames[i] == __mach_task_self ())
257 /* For the name we use for our own task port,
258 insert the child's task port instead. */
259 insert = newtask;
260 else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
262 /* Get the proc server port for the new task. */
263 if (err = __proc_task2proc (portnames[i], newtask, &insert))
264 LOSE;
266 else if (portnames[i] == thread_self)
268 /* For the name we use for our own thread port, we will
269 insert the thread port for the child main user thread
270 after we create it. */
271 insert = MACH_PORT_NULL;
272 record_refs = &thread_refs;
273 /* Allocate a dead name right for this name as a
274 placeholder, so the kernel will not chose this name
275 for any other new port (it might use it for one of the
276 rights created when a thread is created). */
277 if (err = __mach_port_allocate_name
278 (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
279 LOSE;
281 else if (portnames[i] == _hurd_msgport_thread)
282 /* For the name we use for our signal thread's thread port,
283 we will insert the thread port for the child's signal
284 thread after we create it. */
286 insert = MACH_PORT_NULL;
287 record_refs = &sigthread_refs;
288 /* Allocate a dead name right as a placeholder. */
289 if (err = __mach_port_allocate_name
290 (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
291 LOSE;
293 else
295 /* Skip the name we use for any of our own thread ports. */
296 mach_msg_type_number_t j;
297 for (j = 0; j < nthreads; ++j)
298 if (portnames[i] == threads[j])
299 break;
300 if (j < nthreads)
301 continue;
303 insert = portnames[i];
305 /* Find out how many user references we have for
306 the send right with this name. */
307 if (err = __mach_port_get_refs (__mach_task_self (),
308 portnames[i],
309 MACH_PORT_RIGHT_SEND,
310 record_refs ?: &refs))
311 LOSE;
312 if (insert == MACH_PORT_NULL)
313 continue;
314 if (insert == portnames[i] &&
315 (porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
316 /* This is a dead name; allocate another dead name
317 with the same name in the child. */
318 allocate_dead_name:
319 err = __mach_port_allocate_name (newtask,
320 MACH_PORT_RIGHT_DEAD_NAME,
321 portnames[i]);
322 else
323 /* Insert the chosen send right into the child. */
324 err = __mach_port_insert_right (newtask,
325 portnames[i],
326 insert,
327 MACH_MSG_TYPE_COPY_SEND);
328 switch (err)
330 case KERN_NAME_EXISTS:
332 /* It already has a send right under this name (?!).
333 Well, it starts out with a send right for its task
334 port, and inherits the bootstrap and exception ports
335 from us. */
336 mach_port_t childport;
337 mach_msg_type_name_t poly;
338 assert (__mach_port_extract_right (newtask, portnames[i],
339 MACH_MSG_TYPE_COPY_SEND,
340 &childport,
341 &poly) == 0 &&
342 childport == insert &&
343 __mach_port_deallocate (__mach_task_self (),
344 childport) == 0);
345 break;
348 case KERN_INVALID_CAPABILITY:
349 /* The port just died. It was a send right,
350 and now it's a dead name. */
351 goto allocate_dead_name;
353 default:
354 LOSE;
355 break;
357 case KERN_SUCCESS:
358 /* Give the child as many user references as we have. */
359 if (refs > 1 &&
360 (err = __mach_port_mod_refs (newtask,
361 portnames[i],
362 MACH_PORT_RIGHT_SEND,
363 refs - 1)))
364 LOSE;
369 /* Unlock the standard port cells. The child must unlock its own
370 copies too. */
371 for (i = 0; i < _hurd_nports; ++i)
372 __spin_unlock (&_hurd_ports[i].lock);
373 ports_locked = 0;
375 /* Create the child main user thread and signal thread. */
376 if ((err = __thread_create (newtask, &thread)) ||
377 (err = __thread_create (newtask, &sigthread)))
378 LOSE;
380 /* Insert send rights for those threads. We previously allocated
381 dead name rights with the names we want to give the thread ports
382 in the child as placeholders. Now deallocate them so we can use
383 the names. */
384 if ((err = __mach_port_deallocate (newtask, thread_self)) ||
385 (err = __mach_port_insert_right (newtask, thread_self,
386 thread, MACH_MSG_TYPE_COPY_SEND)))
387 LOSE;
388 /* We have one extra user reference created at the beginning of this
389 function, accounted for by mach_port_names (and which will thus be
390 accounted for in the child below). This extra right gets consumed
391 in the child by the store into _hurd_sigthread in the child fork. */
392 if (thread_refs > 1 &&
393 (err = __mach_port_mod_refs (newtask, thread_self,
394 MACH_PORT_RIGHT_SEND,
395 thread_refs - 1)))
396 LOSE;
397 if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none. */
398 && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||
399 (err = __mach_port_insert_right (newtask, _hurd_msgport_thread,
400 sigthread,
401 MACH_MSG_TYPE_COPY_SEND))))
402 LOSE;
403 if (sigthread_refs > 1 &&
404 (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
405 MACH_PORT_RIGHT_SEND,
406 sigthread_refs - 1)))
407 LOSE;
409 /* This seems like a convenient juncture to copy the proc server's
410 idea of what addresses our argv and envp are found at from the
411 parent into the child. Since we happen to know that the child
412 shares our memory image, it is we who should do this copying. */
414 vm_address_t argv, envp;
415 err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
416 ?: __proc_set_arg_locations (newproc, argv, envp));
417 if (err)
418 LOSE;
421 /* Set the child signal thread up to run the msgport server function
422 using the same signal thread stack copied from our address space.
423 We fetch the state before longjmp'ing it so that miscellaneous
424 registers not affected by longjmp (such as i386 segment registers)
425 are in their normal default state. */
426 statecount = MACHINE_THREAD_STATE_COUNT;
427 if (err = __thread_get_state (_hurd_msgport_thread,
428 MACHINE_THREAD_STATE_FLAVOR,
429 (natural_t *) &state, &statecount))
430 LOSE;
431 #if STACK_GROWTH_UP
432 state.SP = __hurd_sigthread_stack_base;
433 #else
434 state.SP = __hurd_sigthread_stack_end;
435 #endif
436 MACHINE_THREAD_STATE_SET_PC (&state,
437 (unsigned long int) _hurd_msgport_receive);
438 if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
439 (natural_t *) &state, statecount))
440 LOSE;
441 /* We do not thread_resume SIGTHREAD here because the child
442 fork needs to do more setup before it can take signals. */
444 /* Set the child user thread up to return 1 from the setjmp above. */
445 _hurd_longjmp_thread_state (&state, env, 1);
446 if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
447 (natural_t *) &state, statecount))
448 LOSE;
450 /* Get the PID of the child from the proc server. We must do this
451 before calling proc_child below, because at that point any
452 authorized POSIX.1 process may kill the child task with SIGKILL. */
453 if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
454 LOSE;
456 /* Register the child with the proc server. It is important that
457 this be that last thing we do before starting the child thread
458 running. Once proc_child has been done for the task, it appears
459 as a POSIX.1 process. Any errors we get must be detected before
460 this point, and the child must have a message port so it responds
461 to POSIX.1 signals. */
462 if (err = __USEPORT (PROC, __proc_child (port, newtask)))
463 LOSE;
465 /* This must be the absolutely last thing we do; we can't assume that
466 the child will remain alive for even a moment once we do this. We
467 ignore errors because we have committed to the fork and are not
468 allowed to return them after the process becomes visible to
469 POSIX.1 (which happened right above when we called proc_child). */
470 (void) __thread_resume (thread);
472 lose:
473 if (ports_locked)
474 for (i = 0; i < _hurd_nports; ++i)
475 __spin_unlock (&_hurd_ports[i].lock);
477 if (newtask != MACH_PORT_NULL)
479 if (err)
480 __task_terminate (newtask);
481 __mach_port_deallocate (__mach_task_self (), newtask);
483 if (thread != MACH_PORT_NULL)
484 __mach_port_deallocate (__mach_task_self (), thread);
485 if (sigthread != MACH_PORT_NULL)
486 __mach_port_deallocate (__mach_task_self (), sigthread);
487 if (newproc != MACH_PORT_NULL)
488 __mach_port_deallocate (__mach_task_self (), newproc);
489 if (thread_self != MACH_PORT_NULL)
490 __mach_port_deallocate (__mach_task_self (), thread_self);
492 if (portnames)
493 __vm_deallocate (__mach_task_self (),
494 (vm_address_t) portnames,
495 nportnames * sizeof (*portnames));
496 if (porttypes)
497 __vm_deallocate (__mach_task_self (),
498 (vm_address_t) porttypes,
499 nporttypes * sizeof (*porttypes));
500 if (threads)
502 for (i = 0; i < nthreads; ++i)
503 __mach_port_deallocate (__mach_task_self (), threads[i]);
504 __vm_deallocate (__mach_task_self (),
505 (vm_address_t) threads,
506 nthreads * sizeof (*threads));
509 /* Run things that want to run in the parent to restore it to
510 normality. Usually prepare hooks and parent hooks are
511 symmetrical: the prepare hook arrests state in some way for the
512 fork, and the parent hook restores the state for the parent to
513 continue executing normally. */
514 RUN_HOOK (_hurd_fork_parent_hook, ());
516 else
518 struct hurd_sigstate *oldstates;
520 /* We are the child task. Unlock the standard port cells, which were
521 locked in the parent when we copied its memory. The parent has
522 inserted send rights with the names that were in the cells then. */
523 for (i = 0; i < _hurd_nports; ++i)
524 __spin_unlock (&_hurd_ports[i].lock);
526 /* We are the only thread in this new task, so we will
527 take the task-global signals. */
528 _hurd_sigthread = thread_self;
530 /* Unchain the sigstate structures for threads that existed in the
531 parent task but don't exist in this task (the child process).
532 Delay freeing them until later because some of the further setup
533 and unlocking might be required for free to work. */
534 oldstates = _hurd_sigstates;
535 if (oldstates == ss)
536 oldstates = ss->next;
537 else
539 while (_hurd_sigstates->next != ss)
540 _hurd_sigstates = _hurd_sigstates->next;
541 _hurd_sigstates->next = ss->next;
543 ss->next = NULL;
544 _hurd_sigstates = ss;
545 __mutex_unlock (&_hurd_siglock);
547 /* Fetch our new process IDs from the proc server. No need to
548 refetch our pgrp; it is always inherited from the parent (so
549 _hurd_pgrp is already correct), and the proc server will send us a
550 proc_newids notification when it changes. */
551 err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
552 &_hurd_orphaned));
554 /* Run things that want to run in the child task to set up. */
555 RUN_HOOK (_hurd_fork_child_hook, ());
557 /* Set up proc server-assisted fault recovery for the signal thread. */
558 _hurdsig_fault_init ();
560 /* Start the signal thread listening on the message port. */
561 if (!err)
562 err = __thread_resume (_hurd_msgport_thread);
564 /* Free the old sigstate structures. */
565 while (oldstates != NULL)
567 struct hurd_sigstate *next = oldstates->next;
568 free (oldstates);
569 oldstates = next;
571 /* XXX what to do if we have any errors here? */
573 pid = 0;
576 /* Unlock things we locked before creating the child task.
577 They are locked in both the parent and child tasks. */
578 for (i = 0; i < _hurd_fork_locks.n; ++i)
579 __mutex_unlock (_hurd_fork_locks.locks[i]);
581 _hurd_critical_section_unlock (ss);
583 return err ? __hurd_fail (err) : pid;
586 weak_alias (__fork, fork)