/* Utility subroutines for process server
   Copyright (C) 1992 Free Software Foundation

This file is part of the GNU Hurd.

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

The GNU Hurd 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with the GNU Hurd; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Written by Michael I. Bushnell.  */

complete_wait (struct proc *p,
	       int status)
{
  struct rusage ru;
  struct proc *pp = p->p_parent;

  bzero (&ru, sizeof (struct rusage));
  proc_wait_reply (pp->p_wc.pw_reply_port, pp->p_wc.pw_reply_port_type,
		   status, &ru, p->p_pid);
}

free_process (struct proc *p)
{
  struct proc *tp, *tmp;
  struct proc *init = pid_find (1);
  
  *p->p_pidhashloc = HASH_DEL;
  *p->p_taskhashloc = HASH_DEL;
  
  if (!--p->p_login->l_refcnt)
    free (p->p_login);

  
  /* Reparent all children to init -- just attach the head
     and tail of our list. */
  for (tp = p->p_ochild; tp->p_sib; tp = tp->p_sib)
    proc_newids (tp->p_msgport, tp->p_task, 1,
		 tp->p_pgrp->pg_pgid, !tp->p_pgrp->pg_orphcnt);

  proc_newids (tp->p_msgport, tp->p_task, 1, tp->p_pgrp->pg_pgid,
	       !tp->p_pgrp->pg_orphcnt);
  tp->p_sib = init->p_ochild;
  if (init->p_ochild)
    init->p_ochild->p_prevsib = &tp->p_prevsib;
  
  init->p_ochild = p->p_ochild;
  p->p_ochild->p_prevsib = &init->p_ochild;
  
  
  /* Remove ourselves from our parent's list of children */
  *p->p_prevsib = p->p_sib;
  
  leave_pgrp (p);
  
  if (p->p_reqport)
    mach_port_mod_refs (mach_task_self (), p->p_reqport,
			MACH_PORT_RIGHT_RECEIVE, 1);
  if (p->p_msgport)
    mach_port_deallocate (mach_task_self (), p->p_msgport);
  
  free (p);
}
