sysread returning 0 means "connection was closed".
sysread returning undef means "connection is still open but no data is available at this time, or some other error".
Your code wasn't doing what you documented.
#!/usr/bin/perl
use diagnostics;
use strict 'subs';
use strict 'refs';
use Socket;
use IO::Handle;
my $child; #filehandle to child process
my $parent; #filehandle to parent process
my $pid; #Process ID of child process
# r e a d L i n e
# This expects to read one line (\n-terminated, but the newline is cho
+mped).
# Returns the line, which will be empty if no characters are waiting t
+o be read.
sub readLine {
my ($fh) = @_;
my $buf = '';
my $offset = 0;
my $cnt = 0;
my $stat;
do {
$stat = sysread $fh, $buf, 4096-$offset, $offset;
# die "sysread: $!\n" unless defined($stat);
return '' unless defined($stat); ############ DOING WHAT YOU D
+OCUMENTED
$offset += $stat;
} while ($stat and "\n" ne substr($buf, -1));
chomp $buf;
#print STDERR time%100, " #readLine returning <$buf>\n";
return $buf;
} #readLine()
# w r i t e L i n e
# Writes a buffer to the filehandle.
sub writeLine {
my ($fh, $buf) = @_;
my $offset = 0;
my $remaining = length($buf);
do {
my $stat = syswrite($fh, $buf, $remaining, $offset);
die "syswrite: $!\n" unless defined($stat);
$remaining -= $stat;
$offset += $stat;
} while (0 < $remaining);
} #writeLine()
socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
or die "socketpair: $!";
$child->autoflush(1);
$parent->autoflush(1);
$child->blocking(0) or die "blocking: $!\n"; ######### CHANGED
#$parent->blocking(0) or die "blocking: $!\n";
if ($pid = fork()) { #parent
close $parent or die "close: $!\n";
while (1) {
sleep 1;
print STDOUT time%100, ": polling child\n";
if (my $line = readLine($child)) {
print STDOUT time%100, ": received <$line>\n";
if ('E_O_F' eq $line) {
my $stat = wait;
die "wait returned $stat\n" unless $stat == $pid;
print STDOUT time%100, ": child reaped, parent exiting
+\n";
exit 0;
}
} else {
print STDOUT time%100, ": no input from child yet\n";
}
}
} else { #child
die "cannot fork: $!" unless defined $pid;
close $child or die "close: $!\n";
writeLine($parent, time%100 . ": child started\n");
sleep 6;
writeLine($parent, time%100 . ": child wrote again\n");
sleep 2;
writeLine($parent, "E_O_F\n"); #causes termination
close $parent or die "close: $!\n";
print STDOUT time%100, ": child exiting\n";
exit;
}
Outputs:
51: polling child
51: received <50: child started>
52: polling child
52: no input from child yet
53: polling child
53: no input from child yet
54: polling child
54: no input from child yet
55: polling child
55: no input from child yet
56: polling child
56: received <56: child wrote again>
57: polling child
57: no input from child yet
58: child exiting
58: polling child
58: received <E_O_F>
58: child reaped, parent exiting
Is this what you wanted?