Update.
[glibc.git] / sysdeps / mach / hurd / fork.c
blob57f09595b0665ab72315180deb74990b1a6f3f14
1 /* Copyright (C) 1994, 1995, 1996, 1997 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 not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, 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 symbol_set_declare (_hurd_fork_locks)
35 /* Things that want to be called before we fork, to prepare the parent for
36 task_create, when the new child task will inherit our address space. */
37 DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
39 /* Things that want to be called when we are forking, with the above all
40 locked. They are passed the task port of the child. The child process
41 is all set up except for doing proc_child, and has no threads yet. */
42 DEFINE_HOOK (_hurd_fork_setup_hook, (void));
44 /* Things to be run in the child fork. */
45 DEFINE_HOOK (_hurd_fork_child_hook, (void));
47 /* Things to be run in the parent fork. */
48 DEFINE_HOOK (_hurd_fork_parent_hook, (void));
51 /* Clone the calling process, creating an exact copy.
52 Return -1 for errors, 0 to the new process,
53 and the process ID of the new process to the old process. */
54 pid_t
55 __fork (void)
57 jmp_buf env;
58 pid_t pid;
59 size_t i;
60 error_t err;
61 struct hurd_sigstate *volatile ss;
63 ss = _hurd_self_sigstate ();
64 __spin_lock (&ss->critical_section_lock);
66 #undef LOSE
67 #define LOSE assert_perror (err) /* XXX */
69 if (! setjmp (env))
71 process_t newproc;
72 task_t newtask;
73 thread_t thread, sigthread;
74 mach_port_urefs_t thread_refs, sigthread_refs;
75 struct machine_thread_state state;
76 mach_msg_type_number_t statecount;
77 mach_port_t *portnames = NULL;
78 mach_msg_type_number_t nportnames = 0;
79 mach_port_type_t *porttypes = NULL;
80 mach_msg_type_number_t nporttypes = 0;
81 thread_t *threads = NULL;
82 mach_msg_type_number_t nthreads = 0;
83 int ports_locked = 0, stopped = 0;
85 void resume_threads (void)
87 if (! stopped)
88 return;
90 assert (threads);
92 for (i = 0; i < nthreads; ++i)
93 if (threads[i] != ss->thread)
94 __thread_resume (threads[i]);
95 stopped = 0;
98 /* Run things that prepare for forking before we create the task. */
99 RUN_HOOK (_hurd_fork_prepare_hook, ());
101 /* Lock things that want to be locked before we fork. */
103 void *const *p;
104 for (p = symbol_set_first_element (_hurd_fork_locks);
105 ! symbol_set_end_p (_hurd_fork_locks, p);
106 ++p)
107 __mutex_lock (*p);
109 __mutex_lock (&_hurd_siglock);
111 newtask = MACH_PORT_NULL;
112 thread = sigthread = MACH_PORT_NULL;
113 newproc = MACH_PORT_NULL;
115 /* Lock all the port cells for the standard ports while we copy the
116 address space. We want to insert all the send rights into the
117 child with the same names. */
118 for (i = 0; i < _hurd_nports; ++i)
119 __spin_lock (&_hurd_ports[i].lock);
120 ports_locked = 1;
123 /* Stop all other threads while copying the address space,
124 so nothing changes. */
125 err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
126 if (!err)
128 stopped = 1;
130 #define XXX_KERNEL_PAGE_FAULT_BUG /* XXX work around page fault bug in mk */
132 #ifdef XXX_KERNEL_PAGE_FAULT_BUG
133 /* Gag me with a pitchfork.
134 The bug scenario is this:
136 - The page containing __mach_task_self_ is paged out.
137 - The signal thread was faulting on that page when we
138 suspended it via proc_dostop. It holds some lock, or set
139 some busy bit, or somesuch.
140 - Now this thread faults on that same page.
141 - GRATUIOUS DEADLOCK
143 We can break the deadlock by aborting the thread that faulted
144 first, which if the bug happened was the signal thread because
145 it is the only other thread and we just suspended it.
147 __thread_abort (_hurd_msgport_thread);
148 #endif
149 /* Create the child task. It will inherit a copy of our memory. */
150 err = __task_create (__mach_task_self (), 1, &newtask);
153 /* Unlock the global signal state lock, so we do not
154 block the signal thread any longer than necessary. */
155 __mutex_unlock (&_hurd_siglock);
157 if (err)
158 LOSE;
160 /* Fetch the names of all ports used in this task. */
161 if (err = __mach_port_names (__mach_task_self (),
162 &portnames, &nportnames,
163 &porttypes, &nporttypes))
164 LOSE;
165 if (nportnames != nporttypes)
167 err = EGRATUITOUS;
168 LOSE;
171 /* Get send rights for all the threads in this task.
172 We want to avoid giving these rights to the child. */
173 if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
174 LOSE;
176 /* Get the child process's proc server port. We will insert it into
177 the child with the same name as we use for our own proc server
178 port; and we will need it to set the child's message port. */
179 if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
180 newtask, &newproc))
181 LOSE;
183 /* Insert all our port rights into the child task. */
184 thread_refs = sigthread_refs = 0;
185 for (i = 0; i < nportnames; ++i)
187 if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
189 /* This is a receive right. We want to give the child task
190 its own new receive right under the same name. */
191 err = __mach_port_allocate_name (newtask,
192 MACH_PORT_RIGHT_RECEIVE,
193 portnames[i]);
194 if (err == KERN_NAME_EXISTS)
196 /* It already has a right under this name (?!). Well,
197 there is this bizarre old Mach IPC feature (in #ifdef
198 MACH_IPC_COMPAT in the ukernel) which results in new
199 tasks getting a new receive right for task special
200 port number 2. What else might be going on I'm not
201 sure. So let's check. */
202 #if !MACH_IPC_COMPAT
203 #define TASK_NOTIFY_PORT 2
204 #endif
205 assert (({ mach_port_t thisport, notify_port;
206 mach_msg_type_name_t poly;
207 (__task_get_special_port (newtask,
208 TASK_NOTIFY_PORT,
209 &notify_port) == 0 &&
210 __mach_port_extract_right
211 (newtask,
212 portnames[i],
213 MACH_MSG_TYPE_MAKE_SEND,
214 &thisport, &poly) == 0 &&
215 (thisport == notify_port) &&
216 __mach_port_deallocate (__mach_task_self (),
217 thisport) == 0 &&
218 __mach_port_deallocate (__mach_task_self (),
219 notify_port) == 0);
220 }));
222 else if (err)
223 LOSE;
224 if (porttypes[i] & MACH_PORT_TYPE_SEND)
226 /* Give the child as many send rights for its receive
227 right as we have for ours. */
228 mach_port_urefs_t refs;
229 mach_port_t port;
230 mach_msg_type_name_t poly;
231 if (err = __mach_port_get_refs (__mach_task_self (),
232 portnames[i],
233 MACH_PORT_RIGHT_SEND,
234 &refs))
235 LOSE;
236 if (err = __mach_port_extract_right (newtask,
237 portnames[i],
238 MACH_MSG_TYPE_MAKE_SEND,
239 &port, &poly))
240 LOSE;
241 if (portnames[i] == _hurd_msgport)
243 /* We just created a receive right for the child's
244 message port and are about to insert send rights
245 for it. Now, while we happen to have a send right
246 for it, give it to the proc server. */
247 mach_port_t old;
248 if (err = __proc_setmsgport (newproc, port, &old))
249 LOSE;
250 if (old != MACH_PORT_NULL)
251 /* XXX what to do here? */
252 __mach_port_deallocate (__mach_task_self (), old);
253 /* The new task will receive its own exceptions
254 on its message port. */
255 if (err = __task_set_special_port (newtask,
256 TASK_EXCEPTION_PORT,
257 port))
258 LOSE;
260 if (err = __mach_port_insert_right (newtask,
261 portnames[i],
262 port,
263 MACH_MSG_TYPE_MOVE_SEND))
264 LOSE;
265 if (refs > 1 &&
266 (err = __mach_port_mod_refs (newtask,
267 portnames[i],
268 MACH_PORT_RIGHT_SEND,
269 refs - 1)))
270 LOSE;
272 if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
274 /* Give the child a send-once right for its receive right,
275 since we have one for ours. */
276 mach_port_t port;
277 mach_msg_type_name_t poly;
278 if (err = __mach_port_extract_right
279 (newtask,
280 portnames[i],
281 MACH_MSG_TYPE_MAKE_SEND_ONCE,
282 &port, &poly))
283 LOSE;
284 if (err = __mach_port_insert_right
285 (newtask,
286 portnames[i], port,
287 MACH_MSG_TYPE_MOVE_SEND_ONCE))
288 LOSE;
291 else if (porttypes[i] &
292 (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
294 /* This is a send right or a dead name.
295 Give the child as many references for it as we have. */
296 mach_port_urefs_t refs, *record_refs = NULL;
297 mach_port_t insert;
298 mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
299 if (portnames[i] == newtask)
300 /* Skip the name we use for the child's task port. */
301 continue;
302 if (portnames[i] == __mach_task_self ())
303 /* For the name we use for our own task port,
304 insert the child's task port instead. */
305 insert = newtask;
306 else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
308 /* Get the proc server port for the new task. */
309 if (err = __proc_task2proc (portnames[i], newtask, &insert))
310 LOSE;
311 insert_type = MACH_MSG_TYPE_MOVE_SEND;
313 else if (portnames[i] == ss->thread)
315 /* For the name we use for our own thread port, we will
316 insert the thread port for the child main user thread
317 after we create it. */
318 insert = MACH_PORT_NULL;
319 record_refs = &thread_refs;
320 /* Allocate a dead name right for this name as a
321 placeholder, so the kernel will not chose this name
322 for any other new port (it might use it for one of the
323 rights created when a thread is created). */
324 if (err = __mach_port_allocate_name
325 (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
326 LOSE;
328 else if (portnames[i] == _hurd_msgport_thread)
329 /* For the name we use for our signal thread's thread port,
330 we will insert the thread port for the child's signal
331 thread after we create it. */
333 insert = MACH_PORT_NULL;
334 record_refs = &sigthread_refs;
335 /* Allocate a dead name right as a placeholder. */
336 if (err = __mach_port_allocate_name
337 (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
338 LOSE;
340 else
342 /* Skip the name we use for any of our own thread ports. */
343 mach_msg_type_number_t j;
344 for (j = 0; j < nthreads; ++j)
345 if (portnames[i] == threads[j])
346 break;
347 if (j < nthreads)
348 continue;
350 /* Copy our own send right. */
351 insert = portnames[i];
353 /* Find out how many user references we have for
354 the send right with this name. */
355 if (err = __mach_port_get_refs (__mach_task_self (),
356 portnames[i],
357 MACH_PORT_RIGHT_SEND,
358 record_refs ?: &refs))
359 LOSE;
360 if (insert == MACH_PORT_NULL)
361 continue;
362 if (insert == portnames[i] &&
363 (porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
364 /* This is a dead name; allocate another dead name
365 with the same name in the child. */
366 allocate_dead_name:
367 err = __mach_port_allocate_name (newtask,
368 MACH_PORT_RIGHT_DEAD_NAME,
369 portnames[i]);
370 else
371 /* Insert the chosen send right into the child. */
372 err = __mach_port_insert_right (newtask,
373 portnames[i],
374 insert,
375 MACH_MSG_TYPE_COPY_SEND);
376 switch (err)
378 case KERN_NAME_EXISTS:
380 /* It already has a send right under this name (?!).
381 Well, it starts out with a send right for its task
382 port, and inherits the bootstrap and exception ports
383 from us. */
384 mach_port_t childport;
385 mach_msg_type_name_t poly;
386 assert (__mach_port_extract_right (newtask, portnames[i],
387 MACH_MSG_TYPE_COPY_SEND,
388 &childport,
389 &poly) == 0 &&
390 childport == insert &&
391 __mach_port_deallocate (__mach_task_self (),
392 childport) == 0);
393 break;
396 case KERN_INVALID_CAPABILITY:
397 /* The port just died. It was a send right,
398 and now it's a dead name. */
399 goto allocate_dead_name;
401 default:
402 LOSE;
403 break;
405 case KERN_SUCCESS:
406 /* Give the child as many user references as we have. */
407 if (refs > 1 &&
408 (err = __mach_port_mod_refs (newtask,
409 portnames[i],
410 MACH_PORT_RIGHT_SEND,
411 refs - 1)))
412 LOSE;
417 /* Unlock the standard port cells. The child must unlock its own
418 copies too. */
419 for (i = 0; i < _hurd_nports; ++i)
420 __spin_unlock (&_hurd_ports[i].lock);
421 ports_locked = 0;
423 /* All state has now been copied from the parent. It is safe to
424 resume other parent threads. */
425 resume_threads ();
427 /* Create the child main user thread and signal thread. */
428 if ((err = __thread_create (newtask, &thread)) ||
429 (err = __thread_create (newtask, &sigthread)))
430 LOSE;
432 /* Insert send rights for those threads. We previously allocated
433 dead name rights with the names we want to give the thread ports
434 in the child as placeholders. Now deallocate them so we can use
435 the names. */
436 if ((err = __mach_port_deallocate (newtask, ss->thread)) ||
437 (err = __mach_port_insert_right (newtask, ss->thread,
438 thread, MACH_MSG_TYPE_COPY_SEND)))
439 LOSE;
440 /* We have one extra user reference created at the beginning of this
441 function, accounted for by mach_port_names (and which will thus be
442 accounted for in the child below). This extra right gets consumed
443 in the child by the store into _hurd_sigthread in the child fork. */
444 if (thread_refs > 1 &&
445 (err = __mach_port_mod_refs (newtask, ss->thread,
446 MACH_PORT_RIGHT_SEND,
447 thread_refs)))
448 LOSE;
449 if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none. */
450 && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||
451 (err = __mach_port_insert_right (newtask, _hurd_msgport_thread,
452 sigthread,
453 MACH_MSG_TYPE_COPY_SEND))))
454 LOSE;
455 if (sigthread_refs > 1 &&
456 (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
457 MACH_PORT_RIGHT_SEND,
458 sigthread_refs - 1)))
459 LOSE;
461 /* This seems like a convenient juncture to copy the proc server's
462 idea of what addresses our argv and envp are found at from the
463 parent into the child. Since we happen to know that the child
464 shares our memory image, it is we who should do this copying. */
466 vm_address_t argv, envp;
467 err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
468 ?: __proc_set_arg_locations (newproc, argv, envp));
469 if (err)
470 LOSE;
473 /* Set the child signal thread up to run the msgport server function
474 using the same signal thread stack copied from our address space.
475 We fetch the state before longjmp'ing it so that miscellaneous
476 registers not affected by longjmp (such as i386 segment registers)
477 are in their normal default state. */
478 statecount = MACHINE_THREAD_STATE_COUNT;
479 if (err = __thread_get_state (_hurd_msgport_thread,
480 MACHINE_THREAD_STATE_FLAVOR,
481 (natural_t *) &state, &statecount))
482 LOSE;
483 #if STACK_GROWTH_UP
484 state.SP = __hurd_sigthread_stack_base;
485 #else
486 state.SP = __hurd_sigthread_stack_end;
487 #endif
488 MACHINE_THREAD_STATE_SET_PC (&state,
489 (unsigned long int) _hurd_msgport_receive);
490 if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
491 (natural_t *) &state, statecount))
492 LOSE;
493 /* We do not thread_resume SIGTHREAD here because the child
494 fork needs to do more setup before it can take signals. */
496 /* Set the child user thread up to return 1 from the setjmp above. */
497 _hurd_longjmp_thread_state (&state, env, 1);
498 if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
499 (natural_t *) &state, statecount))
500 LOSE;
502 /* Get the PID of the child from the proc server. We must do this
503 before calling proc_child below, because at that point any
504 authorized POSIX.1 process may kill the child task with SIGKILL. */
505 if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
506 LOSE;
508 /* Register the child with the proc server. It is important that
509 this be that last thing we do before starting the child thread
510 running. Once proc_child has been done for the task, it appears
511 as a POSIX.1 process. Any errors we get must be detected before
512 this point, and the child must have a message port so it responds
513 to POSIX.1 signals. */
514 if (err = __USEPORT (PROC, __proc_child (port, newtask)))
515 LOSE;
517 /* This must be the absolutely last thing we do; we can't assume that
518 the child will remain alive for even a moment once we do this. We
519 ignore errors because we have committed to the fork and are not
520 allowed to return them after the process becomes visible to
521 POSIX.1 (which happened right above when we called proc_child). */
522 (void) __thread_resume (thread);
524 lose:
525 if (ports_locked)
526 for (i = 0; i < _hurd_nports; ++i)
527 __spin_unlock (&_hurd_ports[i].lock);
529 resume_threads ();
531 if (newtask != MACH_PORT_NULL)
533 if (err)
534 __task_terminate (newtask);
535 __mach_port_deallocate (__mach_task_self (), newtask);
537 if (thread != MACH_PORT_NULL)
538 __mach_port_deallocate (__mach_task_self (), thread);
539 if (sigthread != MACH_PORT_NULL)
540 __mach_port_deallocate (__mach_task_self (), sigthread);
541 if (newproc != MACH_PORT_NULL)
542 __mach_port_deallocate (__mach_task_self (), newproc);
544 if (portnames)
545 __vm_deallocate (__mach_task_self (),
546 (vm_address_t) portnames,
547 nportnames * sizeof (*portnames));
548 if (porttypes)
549 __vm_deallocate (__mach_task_self (),
550 (vm_address_t) porttypes,
551 nporttypes * sizeof (*porttypes));
552 if (threads)
554 for (i = 0; i < nthreads; ++i)
555 __mach_port_deallocate (__mach_task_self (), threads[i]);
556 __vm_deallocate (__mach_task_self (),
557 (vm_address_t) threads,
558 nthreads * sizeof (*threads));
561 /* Run things that want to run in the parent to restore it to
562 normality. Usually prepare hooks and parent hooks are
563 symmetrical: the prepare hook arrests state in some way for the
564 fork, and the parent hook restores the state for the parent to
565 continue executing normally. */
566 RUN_HOOK (_hurd_fork_parent_hook, ());
568 else
570 struct hurd_sigstate *oldstates;
572 /* We are the child task. Unlock the standard port cells, which were
573 locked in the parent when we copied its memory. The parent has
574 inserted send rights with the names that were in the cells then. */
575 for (i = 0; i < _hurd_nports; ++i)
576 __spin_unlock (&_hurd_ports[i].lock);
578 /* We are the only thread in this new task, so we will
579 take the task-global signals. */
580 _hurd_sigthread = ss->thread;
582 /* Unchain the sigstate structures for threads that existed in the
583 parent task but don't exist in this task (the child process).
584 Delay freeing them until later because some of the further setup
585 and unlocking might be required for free to work. */
586 oldstates = _hurd_sigstates;
587 if (oldstates == ss)
588 oldstates = ss->next;
589 else
591 while (_hurd_sigstates->next != ss)
592 _hurd_sigstates = _hurd_sigstates->next;
593 _hurd_sigstates->next = ss->next;
595 ss->next = NULL;
596 _hurd_sigstates = ss;
597 __mutex_unlock (&_hurd_siglock);
599 /* Fetch our new process IDs from the proc server. No need to
600 refetch our pgrp; it is always inherited from the parent (so
601 _hurd_pgrp is already correct), and the proc server will send us a
602 proc_newids notification when it changes. */
603 err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
604 &_hurd_orphaned));
606 /* Forking clears the trace flag. */
607 __sigemptyset (&_hurdsig_traced);
609 /* Run things that want to run in the child task to set up. */
610 RUN_HOOK (_hurd_fork_child_hook, ());
612 /* Set up proc server-assisted fault recovery for the signal thread. */
613 _hurdsig_fault_init ();
615 /* Start the signal thread listening on the message port. */
616 if (!err)
617 err = __thread_resume (_hurd_msgport_thread);
619 /* Free the old sigstate structures. */
620 while (oldstates != NULL)
622 struct hurd_sigstate *next = oldstates->next;
623 free (oldstates);
624 oldstates = next;
626 /* XXX what to do if we have any errors here? */
628 pid = 0;
631 /* Unlock things we locked before creating the child task.
632 They are locked in both the parent and child tasks. */
634 void *const *p;
635 for (p = symbol_set_first_element (_hurd_fork_locks);
636 ! symbol_set_end_p (_hurd_fork_locks, p);
637 ++p)
638 __mutex_unlock (*p);
641 _hurd_critical_section_unlock (ss);
643 return err ? __hurd_fail (err) : pid;
646 weak_alias (__fork, fork)