/* Copyright (C) 1994-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <unistd.h>
#include <hurd.h>
#include <hurd/signal.h>
#include <setjmp.h>
#include <thread_state.h>
#include <sysdep.h>		/* For stack growth direction.  */
#include "set-hooks.h"
#include <assert.h>
#include "hurdmalloc.h"		/* XXX */
#include <tls.h>

#undef __fork


/* Things that want to be locked while forking.  */
symbol_set_declare (_hurd_fork_locks)


/* Application callbacks registered through pthread_atfork.  */
DEFINE_HOOK (_hurd_atfork_prepare_hook, (void));
DEFINE_HOOK (_hurd_atfork_child_hook, (void));
DEFINE_HOOK (_hurd_atfork_parent_hook, (void));

/* Things that want to be called before we fork, to prepare the parent for
   task_create, when the new child task will inherit our address space.  */
DEFINE_HOOK (_hurd_fork_prepare_hook, (void));

/* Things that want to be called when we are forking, with the above all
   locked.  They are passed the task port of the child.  The child process
   is all set up except for doing proc_child, and has no threads yet.  */
DEFINE_HOOK (_hurd_fork_setup_hook, (void));

/* Things to be run in the child fork.  */
DEFINE_HOOK (_hurd_fork_child_hook, (void));

/* Things to be run in the parent fork.  */
DEFINE_HOOK (_hurd_fork_parent_hook, (void));


/* Clone the calling process, creating an exact copy.
   Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
pid_t
__fork (void)
{
  jmp_buf env;
  pid_t pid;
  size_t i;
  error_t err;
  struct hurd_sigstate *volatile ss;

  RUN_HOOK (_hurd_atfork_prepare_hook, ());

  ss = _hurd_self_sigstate ();
  __spin_lock (&ss->critical_section_lock);

#undef	LOSE
#define LOSE do { assert_perror (err); goto lose; } while (0) /* XXX */

  if (! setjmp (env))
    {
      process_t newproc;
      task_t newtask;
      thread_t thread, sigthread;
      mach_port_urefs_t thread_refs, sigthread_refs;
      struct machine_thread_state state;
      mach_msg_type_number_t statecount;
      mach_port_t *portnames = NULL;
      mach_msg_type_number_t nportnames = 0;
      mach_port_type_t *porttypes = NULL;
      mach_msg_type_number_t nporttypes = 0;
      thread_t *threads = NULL;
      mach_msg_type_number_t nthreads = 0;
      int ports_locked = 0, stopped = 0;

      void resume_threads (void)
	{
	  if (! stopped)
	    return;

	  assert (threads);

	  for (i = 0; i < nthreads; ++i)
	    if (threads[i] != ss->thread)
	      __thread_resume (threads[i]);
	  stopped = 0;
	}

      /* Run things that prepare for forking before we create the task.  */
      RUN_HOOK (_hurd_fork_prepare_hook, ());

      /* Lock things that want to be locked before we fork.  */
      {
	void *const *p;
	for (p = symbol_set_first_element (_hurd_fork_locks);
	     ! symbol_set_end_p (_hurd_fork_locks, p);
	     ++p)
	  __mutex_lock (*p);
      }
      __mutex_lock (&_hurd_siglock);

      newtask = MACH_PORT_NULL;
      thread = sigthread = MACH_PORT_NULL;
      newproc = MACH_PORT_NULL;

      /* Lock all the port cells for the standard ports while we copy the
	 address space.  We want to insert all the send rights into the
	 child with the same names.  */
      for (i = 0; i < _hurd_nports; ++i)
	__spin_lock (&_hurd_ports[i].lock);
      ports_locked = 1;


      /* Stop all other threads while copying the address space,
	 so nothing changes.  */
      err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
      if (!err)
	{
	  stopped = 1;

#define XXX_KERNEL_PAGE_FAULT_BUG /* XXX work around page fault bug in mk */

#ifdef XXX_KERNEL_PAGE_FAULT_BUG
	  /* Gag me with a pitchfork.
	     The bug scenario is this:

	     - The page containing __mach_task_self_ is paged out.
	     - The signal thread was faulting on that page when we
	       suspended it via proc_dostop.  It holds some lock, or set
	       some busy bit, or somesuch.
	     - Now this thread faults on that same page.
	     - GRATUIOUS DEADLOCK

	     We can break the deadlock by aborting the thread that faulted
	     first, which if the bug happened was the signal thread because
	     it is the only other thread and we just suspended it.
	     */
	  __thread_abort (_hurd_msgport_thread);
#endif
	  /* Create the child task.  It will inherit a copy of our memory.  */
	  err = __task_create (__mach_task_self (),
#ifdef KERN_INVALID_LEDGER
			       NULL, 0,	/* OSF Mach */
#endif
			       1, &newtask);
	}

      /* Unlock the global signal state lock, so we do not
	 block the signal thread any longer than necessary.  */
      __mutex_unlock (&_hurd_siglock);

      if (err)
	LOSE;

      /* Fetch the names of all ports used in this task.  */
      if (err = __mach_port_names (__mach_task_self (),
				   &portnames, &nportnames,
				   &porttypes, &nporttypes))
	LOSE;
      if (nportnames != nporttypes)
	{
	  err = EGRATUITOUS;
	  LOSE;
	}

      /* Get send rights for all the threads in this task.
	 We want to avoid giving these rights to the child.  */
      if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
	LOSE;

      /* Get the child process's proc server port.  We will insert it into
	 the child with the same name as we use for our own proc server
	 port; and we will need it to set the child's message port.  */
      if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
				  newtask, &newproc))
	LOSE;

      /* Insert all our port rights into the child task.  */
      thread_refs = sigthread_refs = 0;
      for (i = 0; i < nportnames; ++i)
	{
	  if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
	    {
	      /* This is a receive right.  We want to give the child task
		 its own new receive right under the same name.  */
	      err = __mach_port_allocate_name (newtask,
					       MACH_PORT_RIGHT_RECEIVE,
					       portnames[i]);
	      if (err == KERN_NAME_EXISTS)
		{
		  /* It already has a right under this name (?!).  Well,
		     there is this bizarre old Mach IPC feature (in #ifdef
		     MACH_IPC_COMPAT in the ukernel) which results in new
		     tasks getting a new receive right for task special
		     port number 2.  What else might be going on I'm not
		     sure.  So let's check.  */
#if !MACH_IPC_COMPAT
#define TASK_NOTIFY_PORT 2
#endif
		  assert (({ mach_port_t thisport, notify_port;
			     mach_msg_type_name_t poly;
			     (__task_get_special_port (newtask,
						       TASK_NOTIFY_PORT,
						       &notify_port) == 0 &&
			      __mach_port_extract_right
			      (newtask,
			       portnames[i],
			       MACH_MSG_TYPE_MAKE_SEND,
			       &thisport, &poly) == 0 &&
			      (thisport == notify_port) &&
			      __mach_port_deallocate (__mach_task_self (),
						      thisport) == 0 &&
			      __mach_port_deallocate (__mach_task_self (),
						      notify_port) == 0);
			   }));
		}
	      else if (err)
		LOSE;
	      if (porttypes[i] & MACH_PORT_TYPE_SEND)
		{
		  /* Give the child as many send rights for its receive
		     right as we have for ours.  */
		  mach_port_urefs_t refs;
		  mach_port_t port;
		  mach_msg_type_name_t poly;
		  if (err = __mach_port_get_refs (__mach_task_self (),
						  portnames[i],
						  MACH_PORT_RIGHT_SEND,
						  &refs))
		    LOSE;
		  if (err = __mach_port_extract_right (newtask,
						       portnames[i],
						       MACH_MSG_TYPE_MAKE_SEND,
						       &port, &poly))
		    LOSE;
		  if (portnames[i] == _hurd_msgport)
		    {
		      /* We just created a receive right for the child's
			 message port and are about to insert send rights
			 for it.  Now, while we happen to have a send right
			 for it, give it to the proc server.  */
		      mach_port_t old;
		      if (err = __proc_setmsgport (newproc, port, &old))
			LOSE;
		      if (old != MACH_PORT_NULL)
			/* XXX what to do here? */
			__mach_port_deallocate (__mach_task_self (), old);
		      /* The new task will receive its own exceptions
			 on its message port.  */
		      if (err =
#ifdef TASK_EXCEPTION_PORT
			  __task_set_special_port (newtask,
						   TASK_EXCEPTION_PORT,
						   port)
#elif defined (EXC_MASK_ALL)
			  __task_set_exception_ports
			  (newtask, EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
						     | EXC_MASK_MACH_SYSCALL
						     | EXC_MASK_RPC_ALERT),
			   port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
#else
# error task_set_exception_port?
#endif
			  )
			LOSE;
		    }
		  if (err = __mach_port_insert_right (newtask,
						      portnames[i],
						      port,
						      MACH_MSG_TYPE_MOVE_SEND))
		    LOSE;
		  if (refs > 1 &&
		      (err = __mach_port_mod_refs (newtask,
						   portnames[i],
						   MACH_PORT_RIGHT_SEND,
						   refs - 1)))
		    LOSE;
		}
	      if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
		{
		  /* Give the child a send-once right for its receive right,
		     since we have one for ours.  */
		  mach_port_t port;
		  mach_msg_type_name_t poly;
		  if (err = __mach_port_extract_right
		      (newtask,
		       portnames[i],
		       MACH_MSG_TYPE_MAKE_SEND_ONCE,
		       &port, &poly))
		    LOSE;
		  if (err = __mach_port_insert_right
		      (newtask,
		       portnames[i], port,
		       MACH_MSG_TYPE_MOVE_SEND_ONCE))
		    LOSE;
		}
	    }
	  else if (porttypes[i] &
		   (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
	    {
	      /* This is a send right or a dead name.
		 Give the child as many references for it as we have.  */
	      mach_port_urefs_t refs = 0, *record_refs = NULL;
	      mach_port_t insert;
	      mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
	      if (portnames[i] == newtask || portnames[i] == newproc)
		/* Skip the name we use for the child's task or proc ports.  */
		continue;
	      if (portnames[i] == __mach_task_self ())
		/* For the name we use for our own task port,
		   insert the child's task port instead.  */
		insert = newtask;
	      else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
		{
		  /* Use the proc server port for the new task.  */
		  insert = newproc;
		  insert_type = MACH_MSG_TYPE_COPY_SEND;
		}
	      else if (portnames[i] == ss->thread)
		{
		  /* For the name we use for our own thread port, we will
		     insert the thread port for the child main user thread
		     after we create it.  */
		  insert = MACH_PORT_NULL;
		  record_refs = &thread_refs;
		  /* Allocate a dead name right for this name as a
		     placeholder, so the kernel will not chose this name
		     for any other new port (it might use it for one of the
		     rights created when a thread is created).  */
		  if (err = __mach_port_allocate_name
		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
		    LOSE;
		}
	      else if (portnames[i] == _hurd_msgport_thread)
		/* For the name we use for our signal thread's thread port,
		   we will insert the thread port for the child's signal
		   thread after we create it.  */
		{
		  insert = MACH_PORT_NULL;
		  record_refs = &sigthread_refs;
		  /* Allocate a dead name right as a placeholder.  */
		  if (err = __mach_port_allocate_name
		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
		    LOSE;
		}
	      else
		{
		  /* Skip the name we use for any of our own thread ports.  */
		  mach_msg_type_number_t j;
		  for (j = 0; j < nthreads; ++j)
		    if (portnames[i] == threads[j])
		      break;
		  if (j < nthreads)
		    continue;

		  /* Copy our own send right.  */
		  insert = portnames[i];
		}
	      /* Find out how many user references we have for
		 the send right with this name.  */
	      if (err = __mach_port_get_refs (__mach_task_self (),
					      portnames[i],
					      MACH_PORT_RIGHT_SEND,
					      record_refs ?: &refs))
		LOSE;
	      if (insert == MACH_PORT_NULL)
		continue;
	      if (insert == portnames[i] &&
		  (porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
		/* This is a dead name; allocate another dead name
		   with the same name in the child.  */
	      allocate_dead_name:
		err = __mach_port_allocate_name (newtask,
						 MACH_PORT_RIGHT_DEAD_NAME,
						 portnames[i]);
	      else
		/* Insert the chosen send right into the child.  */
		err = __mach_port_insert_right (newtask,
						portnames[i],
						insert, insert_type);
	      switch (err)
		{
		case KERN_NAME_EXISTS:
		  {
		    /* It already has a send right under this name (?!).
		       Well, it starts out with a send right for its task
		       port, and inherits the bootstrap and exception ports
		       from us.  */
		    mach_port_t childport;
		    mach_msg_type_name_t poly;
		    assert (__mach_port_extract_right (newtask, portnames[i],
						       MACH_MSG_TYPE_COPY_SEND,
						       &childport,
						       &poly) == 0 &&
			    childport == insert &&
			    __mach_port_deallocate (__mach_task_self (),
						    childport) == 0);
		    break;
		  }

		case KERN_INVALID_CAPABILITY:
		  /* The port just died.  It was a send right,
		     and now it's a dead name.  */
		  goto allocate_dead_name;

		default:
		  LOSE;
		  break;

		case KERN_SUCCESS:
		  /* Give the child as many user references as we have.  */
		  if (refs > 1 &&
		      (err = __mach_port_mod_refs (newtask,
						   portnames[i],
						   MACH_PORT_RIGHT_SEND,
						   refs - 1)))
		    LOSE;
		}
	    }
	}

      /* Unlock the standard port cells.  The child must unlock its own
	 copies too.  */
      for (i = 0; i < _hurd_nports; ++i)
	__spin_unlock (&_hurd_ports[i].lock);
      ports_locked = 0;

      /* All state has now been copied from the parent.  It is safe to
	 resume other parent threads.  */
      resume_threads ();

      /* Create the child main user thread and signal thread.  */
      if ((err = __thread_create (newtask, &thread)) ||
	  (err = __thread_create (newtask, &sigthread)))
	LOSE;

      /* Insert send rights for those threads.  We previously allocated
	 dead name rights with the names we want to give the thread ports
	 in the child as placeholders.  Now deallocate them so we can use
	 the names.  */
      if ((err = __mach_port_deallocate (newtask, ss->thread)) ||
	  (err = __mach_port_insert_right (newtask, ss->thread,
					   thread, MACH_MSG_TYPE_COPY_SEND)))
	LOSE;
      /* We have one extra user reference created at the beginning of this
	 function, accounted for by mach_port_names (and which will thus be
	 accounted for in the child below).  This extra right gets consumed
	 in the child by the store into _hurd_sigthread in the child fork.  */
      if (thread_refs > 1 &&
	  (err = __mach_port_mod_refs (newtask, ss->thread,
				       MACH_PORT_RIGHT_SEND,
				       thread_refs)))
	LOSE;
      if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none.  */
	  && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||
	      (err = __mach_port_insert_right (newtask, _hurd_msgport_thread,
					       sigthread,
					       MACH_MSG_TYPE_COPY_SEND))))
	LOSE;
      if (sigthread_refs > 1 &&
	  (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
				       MACH_PORT_RIGHT_SEND,
				       sigthread_refs - 1)))
	LOSE;

      /* This seems like a convenient juncture to copy the proc server's
	 idea of what addresses our argv and envp are found at from the
	 parent into the child.  Since we happen to know that the child
	 shares our memory image, it is we who should do this copying.  */
      {
	vm_address_t argv, envp;
	err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
	       ?: __proc_set_arg_locations (newproc, argv, envp));
	if (err)
	  LOSE;
      }

      /* Set the child signal thread up to run the msgport server function
	 using the same signal thread stack copied from our address space.
	 We fetch the state before longjmp'ing it so that miscellaneous
	 registers not affected by longjmp (such as i386 segment registers)
	 are in their normal default state.  */
      statecount = MACHINE_THREAD_STATE_COUNT;
      if (err = __thread_get_state (_hurd_msgport_thread,
				    MACHINE_THREAD_STATE_FLAVOR,
				    (natural_t *) &state, &statecount))
	LOSE;
#if STACK_GROWTH_UP
#define THREADVAR_SPACE (__hurd_threadvar_max \
			 * sizeof *__hurd_sightread_variables)
      if (__hurd_sigthread_stack_base == 0)
	{
	  state.SP &= __hurd_threadvar_stack_mask;
	  state.SP += __hurd_threadvar_stack_offset + THREADVAR_SPACE;
	}
      else
	state.SP = __hurd_sigthread_stack_base;
#else
      if (__hurd_sigthread_stack_end == 0)
	{
	  /* The signal thread has a normal stack assigned by cthreads.
	     The threadvar_stack variables conveniently tell us how
	     to get to the highest address in the stack, just below
	     the per-thread variables.  */
	  state.SP &= __hurd_threadvar_stack_mask;
	  state.SP += __hurd_threadvar_stack_offset;
	}
      else
	state.SP = __hurd_sigthread_stack_end;
#endif
      MACHINE_THREAD_STATE_SET_PC (&state,
				   (unsigned long int) _hurd_msgport_receive);
      if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
				    (natural_t *) &state, statecount))
	LOSE;
      /* We do not thread_resume SIGTHREAD here because the child
	 fork needs to do more setup before it can take signals.  */

      /* Set the child user thread up to return 1 from the setjmp above.  */
      _hurd_longjmp_thread_state (&state, env, 1);

      /* Do special thread setup for TLS if needed.  */
      if (err = _hurd_tls_fork (thread, &state))
	LOSE;

      if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
				    (natural_t *) &state, statecount))
	LOSE;

      /* Get the PID of the child from the proc server.  We must do this
	 before calling proc_child below, because at that point any
	 authorized POSIX.1 process may kill the child task with SIGKILL.  */
      if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
	LOSE;

      /* Register the child with the proc server.  It is important that
	 this be that last thing we do before starting the child thread
	 running.  Once proc_child has been done for the task, it appears
	 as a POSIX.1 process.  Any errors we get must be detected before
	 this point, and the child must have a message port so it responds
	 to POSIX.1 signals.  */
      if (err = __USEPORT (PROC, __proc_child (port, newtask)))
	LOSE;

      /* This must be the absolutely last thing we do; we can't assume that
	 the child will remain alive for even a moment once we do this.  We
	 ignore errors because we have committed to the fork and are not
	 allowed to return them after the process becomes visible to
	 POSIX.1 (which happened right above when we called proc_child).  */
      (void) __thread_resume (thread);

    lose:
      if (ports_locked)
	for (i = 0; i < _hurd_nports; ++i)
	  __spin_unlock (&_hurd_ports[i].lock);

      resume_threads ();

      if (newtask != MACH_PORT_NULL)
	{
	  if (err)
	    __task_terminate (newtask);
	  __mach_port_deallocate (__mach_task_self (), newtask);
	}
      if (thread != MACH_PORT_NULL)
	__mach_port_deallocate (__mach_task_self (), thread);
      if (sigthread != MACH_PORT_NULL)
	__mach_port_deallocate (__mach_task_self (), sigthread);
      if (newproc != MACH_PORT_NULL)
	__mach_port_deallocate (__mach_task_self (), newproc);

      if (portnames)
	__vm_deallocate (__mach_task_self (),
			 (vm_address_t) portnames,
			 nportnames * sizeof (*portnames));
      if (porttypes)
	__vm_deallocate (__mach_task_self (),
			 (vm_address_t) porttypes,
			 nporttypes * sizeof (*porttypes));
      if (threads)
	{
	  for (i = 0; i < nthreads; ++i)
	    __mach_port_deallocate (__mach_task_self (), threads[i]);
	  __vm_deallocate (__mach_task_self (),
			   (vm_address_t) threads,
			   nthreads * sizeof (*threads));
	}

      /* Run things that want to run in the parent to restore it to
	 normality.  Usually prepare hooks and parent hooks are
	 symmetrical: the prepare hook arrests state in some way for the
	 fork, and the parent hook restores the state for the parent to
	 continue executing normally.  */
      RUN_HOOK (_hurd_fork_parent_hook, ());
    }
  else
    {
      struct hurd_sigstate *oldstates;

      /* We are the child task.  Unlock the standard port cells, which were
	 locked in the parent when we copied its memory.  The parent has
	 inserted send rights with the names that were in the cells then.  */
      for (i = 0; i < _hurd_nports; ++i)
	__spin_unlock (&_hurd_ports[i].lock);

      /* We are one of the (exactly) two threads in this new task, we
	 will take the task-global signals.  */
      _hurd_sigthread = ss->thread;

      /* Claim our sigstate structure and unchain the rest: the
	 threads existed in the parent task but don't exist in this
	 task (the child process).  Delay freeing them until later
	 because some of the further setup and unlocking might be
	 required for free to work.  Before we finish cleaning up,
	 we will reclaim the signal thread's sigstate structure (if
	 it had one).  */
      oldstates = _hurd_sigstates;
      if (oldstates == ss)
	oldstates = ss->next;
      else
	{
	  while (_hurd_sigstates->next != ss)
	    _hurd_sigstates = _hurd_sigstates->next;
	  _hurd_sigstates->next = ss->next;
	}
      ss->next = NULL;
      _hurd_sigstates = ss;
      __mutex_unlock (&_hurd_siglock);

      /* Fetch our new process IDs from the proc server.  No need to
	 refetch our pgrp; it is always inherited from the parent (so
	 _hurd_pgrp is already correct), and the proc server will send us a
	 proc_newids notification when it changes.  */
      err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
					     &_hurd_orphaned));

      /* Forking clears the trace flag.  */
      __sigemptyset (&_hurdsig_traced);

      /* Run things that want to run in the child task to set up.  */
      RUN_HOOK (_hurd_fork_child_hook, ());

      /* Set up proc server-assisted fault recovery for the signal thread.  */
      _hurdsig_fault_init ();

      /* Start the signal thread listening on the message port.  */
      if (!err)
	err = __thread_resume (_hurd_msgport_thread);

      /* Reclaim the signal thread's sigstate structure and free the
	 other old sigstate structures.  */
      while (oldstates != NULL)
	{
	  struct hurd_sigstate *next = oldstates->next;

	  if (oldstates->thread == _hurd_msgport_thread)
	    {
	      /* If we have a second signal state structure then we
		 must have been through here before--not good.  */
	      assert (_hurd_sigstates->next == 0);
	      _hurd_sigstates->next = oldstates;
	      oldstates->next = 0;
	    }
	  else
	    free (oldstates);

	  oldstates = next;
	}

      /* XXX what to do if we have any errors here? */

      pid = 0;
    }

  /* Unlock things we locked before creating the child task.
     They are locked in both the parent and child tasks.  */
  {
    void *const *p;
    for (p = symbol_set_first_element (_hurd_fork_locks);
	 ! symbol_set_end_p (_hurd_fork_locks, p);
	 ++p)
      __mutex_unlock (*p);
  }

  _hurd_critical_section_unlock (ss);

  if (!err)
    {
      if (pid != 0)
	RUN_HOOK (_hurd_atfork_parent_hook, ());
      else
	RUN_HOOK (_hurd_atfork_child_hook, ());
    }

  return err ? __hurd_fail (err) : pid;
}
libc_hidden_def (__fork)

weak_alias (__fork, fork)
