#!/usr/bin/perl use strict; use warnings; my $parent_pid = $$; my $child_pid = 0; my @child_output; my $read_from_child = 0; my $max_timeout = 60; my $timeout; print "Parent is $parent_pid\n"; my $pid = open(KID_TO_READ, "-|"); defined($pid) || die "can't fork: $!"; #local $SIG{CHLD}; if ($pid) { # parent local $SIG{'CHLD'} = sub { print "dead child\n"; $timeout=0 }; local $SIG{'USR1'} = sub { ++$read_from_child }; print "reading kid...\n"; $timeout = $max_timeout; while($timeout >0){ print "parent $parent_pid timeout=$timeout read_from_child=$read_from_child - child_pid=$child_pid\n"; if($read_from_child>0){ --$read_from_child; $_=; print "parent $$ just read: $_"; unless( $child_pid>0 ){ chomp($child_pid = $_); }else{ push @child_output, $_; } }else{ sleep 1; --$timeout; } } close(KID_TO_READ); } else { # child print $$ . "\n"; # send child pid kill('USR1', $parent_pid); # warn parent there is data print STDERR "child $$ is running\n"; # print to screen (DEBUG) my $program = "/bin/sleep"; my @args = qw(3); my $ret = system($program, @args); print "returncode is $ret\n"; # is $? print STDERR "returncode is $ret\n"; # print to screen (DEBUG) kill('USR1', $parent_pid); # warn parent there is data exit 0; } print "\nChild $child_pid is done, we now have:\n@child_output\n"; #### Parent is 5323 reading kid... parent 5323 timeout=60 read_from_child=0 - child_pid=0 child 5324 is running parent 5323 timeout=59 read_from_child=1 - child_pid=0 parent 5323 just read: 5324 parent 5323 timeout=59 read_from_child=0 - child_pid=5324 parent 5323 timeout=58 read_from_child=0 - child_pid=5324 parent 5323 timeout=57 read_from_child=0 - child_pid=5324 parent 5323 timeout=56 read_from_child=0 - child_pid=5324 returncode is 0 parent 5323 timeout=55 read_from_child=1 - child_pid=5324 parent 5323 just read: returncode is 0 parent 5323 timeout=55 read_from_child=0 - child_pid=5324 dead child Child 5324 is done, we now have: returncode is 0