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?
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.