in reply to Forked pipe deadlock

Your other child processes are keeping the pipe open for the first one. To demonstrate this, just reverse the order in which you close the pipes:
for (my $i = 3; $i >= 0; $i--) { close($handles[$i]); }
That is, when the parent forks child #2, it will inherit the parent's pipe to child #1, and that is what is keeping child #1 from seeing EOF.

One solution is to explicit close those handles in the new children:

if (!open($handles[$i], "|-") { ...close $handles[0..$i-1]... child(); exit(0); }
Update: Corrected index bounds - thanks psini!

Replies are listed 'Best First'.
Re^2: Forked pipe deadlock
by almut (Canon) on May 25, 2008 at 21:33 UTC
    for (my $i = 3; $i >= 0; $i--) { close($handles[$i]); }

    In Perl, I'd prefer something like this instead of the C style for loop (YMMV of course):

    close $handles[$_] for reverse 0..3;

    (the explicit reverse emphasizes that it's essential here to do something in reverse order of how you'd do it normally)

Re^2: Forked pipe deadlock
by psini (Deacon) on May 25, 2008 at 20:55 UTC

    Ehm, you probably meant:

    for (my $i = 3; $i >= 0; $i--) { close($handles[$i]); }

    Rule One: Do not act incautiously when confronting a little bald wrinkly smiling man.

Re^2: Forked pipe deadlock
by Anonymous Monk on May 25, 2008 at 21:35 UTC
    Thanks - that fixed it. Changed the code to:
    if(!open($handles[$i], '|-')) { # child process foreach $handle (@handles) { defined($handle) && close($handle); } child(); exit 0; }
    I wouldn't have thought of that, so many thanks - very much appreciated.