bug in pclose(3)

Malcolm Purvis malcolm at otc.oz
Thu Dec 22 09:59:33 AEST 1988


In article <261 at ecijmm.UUCP> jmm at ecijmm.UUCP (John Macdonald) writes:

	[Stuff about pclose(3) hanging when there is more than one child...]

>Is this behaviour common to all System 5 variations?  To BSD
>derivatives?  SunOS?  AIX?  Your favourite here?

	It's all of them as for as I know. See below.
>
>Is there even a good general solution?  I can see only one good way
>to handle all of the variations of some routine wanting to wait for
>a specific child and getting the termination info for a different child
>instead (which will eventually be waited for - perhaps by a totally
>different routine).  That would be to provide some new library routines:
>waitfor( child, &status ) and postwait( child, status ).  Waitfor would
>wait for a specified child (and save information internally on any other
>children that terminate in the meantime).  Postwait would allow a routine
>that had done a wait call and gotten the termination for a child that
>it didn't know to pass that info into the mechanism for saving used by
>waitfor.  These routines could be used internally by pclose, system, and
>any other library routines that have waiting for a specific child as a
>part of their semantics, as well as being provided to the user as a new
>pair of library routines for building additional capabilities that include
>forked children as a part of their implementation.
>-- 
>--
>John Macdonald

	I had to solve this problem recently for a C++ subprocess class and
as John said it stems from the inability to wait for a specific child to
die; you can only wait for the next one.  The solution I came up with under
BSD4.3 was to put a structure associated with each child in a linked list
and use a SIGCHLD handler to do the actual waiting.  When the signal
arrives, the wait(2) is done in the handler and the list is searched for the
pid of the dead child and, when it is found, it is marked as dead and taken
off the list.  The inside of the waitfor() call would then look something
like:

		while (!child.dead)
			sigpause(0); /* wait for this process to die. */

		*status = child.return_value;

	This works wonderfully in C++ because as the child structure goes
out of scope the child process is automatically waited for, so stopping
children not having a data structure associated with it, and also each caller
gets the right return value. I don't know, however, how you could do this in
C.  The only problem with all this is that is falls over if the child dies
before it gets inserted into the list (eg: The exec() fails because the
program isn't there) so care must be taken over the order of list insertion
and forking.

	I hope this helps.

			    Malcolm Purvis (vacation student)
			    |||| OTC ||

			ACSnet:  malcolm at otc.oz
			  UUCP:  {uunet,mcvax}!otc.oz!malcolm
			 Snail:  GPO Box 7000, Sydney 2001, Australia



More information about the Comp.unix.wizards mailing list