[comp.bugs.4bsd] Running stdin/out through a pipe to a child process

dce@mips.UUCP (David Elliott) (01/19/87)

With all of this discussion about pipes, I thought I'd bring up the
subject of a (4.[23]BSD) bug involving closing two pipes in succession:

1. A pipe is opened, written to, closed, and the child process is waited on.
After termination, this is done again. All goes as expected.

2. Two pipes are opened and written to. Next, both pipes are closed. Finally,
each child process is waited for. All goes as expected, except that I
find it odd that the second child is found by wait() first. This really
isn't the problem anyway.

3. Two pipes are opened and written two. Afterwards, each pipe is closed and
the child process waited for (that is, pipe 1 is closed and child 1 is
waited for and then pipe 2 is closed and child 2 is waited for). In this
case, the first wait() blocks, and the first child never terminates except
when the parent does.

I have reduced these 3 cases as much as possible by inlining the code for
popen() and pclose() and getting rid of the stdio code used by them (stdio
exists only to print error messages in the programs). The result is a set
of programs that directly call the system calls involved.

If anyone would like to work on this problem, I can send out copies of
these programs (the whole deal is about 8K of source, but I didn't want
to clutter up the net).

-- 
			David Elliott

UUCP: 	{decvax,ucbvax,ihnp4}!decwrl!mips!dce, DDD:  	408-720-1700

chris@mimsy.UUCP (Chris Torek) (01/22/87)

In article <145@quacky.mips.UUCP> dce@mips.UUCP (David Elliott) writes:
>2. Two pipes are opened and written to. Next, both pipes are closed. Finally,
>each child process is waited for. All goes as expected, except that I
>find it odd that the second child is found by wait() first.

Child collection order is not guaranteed anywhere, so do not count
on it working either way.  Yet this is a clue, to those who have keen
sight:

>3. Two pipes are opened and written two [sic]. Afterwards, each pipe
>is closed and the child process waited for (that is, pipe 1 is closed
>and child 1 is waited for and then pipe 2 is closed and child 2 is
>waited for). In this case, the first wait() blocks, and the first
>child never terminates except when the parent does.

An instant analysis:

Child 2 is still able to write to child 1, having in its posession
a descriptor for the write end of the pipe to child 1.  Child 1
will not exit until child 2 exits or otherwise discards this
descriptor.  This should be easy to confirm, by code inspection,
or by adding `gratuitous' close() calls.  This is yet another
example of why it is necessary to use care as to who has descriptors
to which ends of what pipes.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu