BBN-Vax-TCP/src/mtp/spawn.c


#include "errno.h"
/*	Forking is complicated by the fact that a process
 *	that exits becomes a "ZOMBIE".	It does not leave
 *      UNIX until it is waited for by its parent.  There-
 *      fore, the logger creates two processes,
 *	a child and a grandchild, so that the grandchild,
 *	which actually does the work, will be adopted by
 *	the init process when the child exits.
 *
 *      Make sure it waits on the right thing jsq BBN 5Aug79
 *      Put back pipe transfer of granchild id for systems with
 *      full size pids.  jsq BBN 18Feb80.
 */
int par_uid;

spawn ()
{
  int   child,
        grandchild,
        grandparent;
  int   pstat;
  extern int  errno;
  int   pipefds[2];

  while (pipe (pipefds) == -1)
    if (errno != ENFILE)
      return (-1);
    else
      sleep (10);
  par_uid = getpid();
  while ((child = fork ()) == -1)
    sleep (10);
  if (child)
  {                             /* parent waits for pid of grandchild */
    close (pipefds[1]);
    while (wait (&pstat) != child)
      ;
    if (read (pipefds[0], &grandchild, sizeof (grandchild))
	!= sizeof (grandchild))
      grandchild = -1;
    close (pipefds[0]);
    return (grandchild);
  }
  else
  {
    close (pipefds[0]);
    grandparent = par_uid;      /* save (grand)parent uid for use later */
    while ((grandchild = fork ()) == -1)
      sleep (10);
    if (grandchild)
    {
      write (pipefds[1], &grandchild, sizeof (grandchild));
      exit (grandchild);	/* After creating grandchild, exit. */
    }
    par_uid = grandparent;
    close (pipefds[1]);
    return (0);
  }
}