[comp.unix.questions] fork question

davis@pacific.mps.ohio-state.edu ("John E. Davis") (02/07/91)

Hi,

   I have a program, called `sline' with the front end:

   main()
{  
    char *position,*init_status,*exit_status,*terminal;
    int matched;
    int child_pid, parent_pid, parent;
    FILE *fpstatus;

    
    parent_pid = getppid();
    
    /* we create an identical process to do the work and exit the parent */
    /* now fork off a child to do all of the work */
    switch (child_pid = fork())
	{
	  case 0:
	    /* this is the child; let it go on */
	    break;
	  case -1:
	    /* oops... something wrong! */
	    perror("sline");
	    exit(1);
	    break;
	  default:
	    /* the parent... may exit after sending the pid of the child */
	    printf("%d\n",child_pid);
	    exit(0);
	}

[....]

As you can see, the program forks with the parent exiting returning the pid of
the child process.  This is precisely what happens when I run it at the unix
command line.  Now in my .login I have the line:
       .
       .
set slinepid = `sline`
       .
       .


which sets the variable `slinepid' to the pid of the child.  This variable
gets set but my .login gets hung up here-- ie. it does not continue beyond
this point; I have to ^C to kill it.

What fundamental point am I missing here?  It seems to me that the .login is
waiting for the child to exit as well.

Thanks,
--
John

  bitnet: davis@ohstpy
internet: davis@pacific.mps.ohio-state.edu

jik@athena.mit.edu (Jonathan I. Kamens) (02/07/91)

  When you run fork(), the child process that results from the fork() has the
same open file descriptors (except for the ones that are set to close-on-exec)
as the parent process.

  When you use back-quote command evaluation in the shell, the shell keeps
reading on the stdout file descriptor of the process it calls, until it gets
EOF on that file descriptor.

  The shell won't get EOF on the file descriptor until *all* processes that
have the other end of the file descriptor open have closed it (or exited and
implicitly closed it).

  Therefore, although your parent process exits, the shell continues to wait
for output, because the child process still has stdout open, so the shell does
not get an EOF.

  The easiest way to fix this is to close stdout and reopen /dev/null or
something on top of it in the child process.  If you need to output stuff to
stdout in the child, you'll have to come up with something more creative, like
opening /dev/tty for write after closing stdout, or dup'ing stderr's file
descriptor onto stdout, or something like that.  Deciding exactly how to get
back a stdout to write to depends on exactly what your program does.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

barmar@think.com (Barry Margolin) (02/07/91)

In article <DAVIS.91Feb6142453@pacific.mps.ohio-state.edu> davis@pacific.mps.ohio-state.edu  (John E. Davis) writes:
>As you can see, the program forks with the parent exiting returning the pid of
>the child process.  This is precisely what happens when I run it at the unix
>command line.  Now in my .login I have the line:
>set slinepid = `sline`
>which sets the variable `slinepid' to the pid of the child.  This variable
>gets set but my .login gets hung up here-- ie. it does not continue beyond
>this point; I have to ^C to kill it.
>
>What fundamental point am I missing here?  It seems to me that the .login is
>waiting for the child to exit as well.

The child process has to close its stdout.  The problem is that the shell
is reading the pipe until it gets an EOF, and that doesn't happen until all
the processes on the other end of the pipe have closed it.
--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar