in reply to eof() blocking

From perldoc -f eof:

> eof
Returns 1 if the next read on FILEHANDLE will return end of file or if FILEHANDLE is not open. FILEHANDLE may be an expression whose value gives the real filehandle. (Note that this function actually reads a character and then "ungetc"s it, so isn't useful in an interactive context.)

A filehandle to which nothing has been printed is like a Schrödinger's cat. You can't tell whether there will be an eof before something writes to it or closes it.

Update: I like tybalt89's answer, but I guess you wanted to be notified that the parent is waiting for the child. Use IO::Select for that:

#!/usr/bin/perl use warnings; use strict; use Socket; use IO::Select; my ($child, $parent); socketpair $child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC or die "socketpair: $!"; $child->autoflush(1); $parent->autoflush(1); if (my $pid = fork) { close $parent or die "close: $!\n"; print STDOUT time % 100, ": polling child\n"; my $select = 'IO::Select'->new; $select->add($child); my $buf = ''; COMMUNICATION: while (1) { if ($select->can_read(0)) { sysread $child, $buf, 4096, length $buf or last COMMUNICATION; if ($buf =~ s/(.*)\n//) { print STDOUT time % 100, ": received <$1>\n"; } } else { print STDOUT time % 100, ": waiting for child.\n"; sleep 1; } } print STDOUT time % 100, ": end of input from child\n"; wait; } elsif (defined $pid) { close $child or die "close: $!\n"; print STDOUT time % 100, ": child started\n"; sleep 5; print $parent time % 100, ": child printed\n"; sleep 2; print $parent time % 100, ": child printed again\n"; close $parent or die "close: $!\n"; exit } else { die "cannot fork: $!" }
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: eof() blocking
by azadian (Sexton) on Nov 05, 2020 at 10:16 UTC
    In my simple-minded way, I thought a filehandle was an ID of a buffer which either has characters waiting to be read or not. Apparently it's not that simple. Thanks for illustrating how it can be done with IO::Select.