http://qs321.pair.com?node_id=11123415


in reply to Re: eof() blocking
in thread eof() blocking

Thanks for your input. I have a hard time regarding this as an "interactive" context, but I guess the moral of the story is that eof() only works if it's an honest-to-God file. The fact that it blocks seems to me completely contrary to the whole point of the function. The system IO is what I was hoping to avoid, but it looks like I can't.

Replies are listed 'Best First'.
Re^3: eof() blocking
by tybalt89 (Monsignor) on Nov 05, 2020 at 15:15 UTC

    While I'm not completely sure of what you want, it appears to me you are looking for something like a "datawaiting()" call instead of an end-of-file.
    Here's a (somewhat) minimal change to your program with the end-of-file replaced :)

    #!/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 socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $! +"; $child->autoflush(1); $parent->autoflush(1); if ($pid = fork()) { #parent close $parent or die "close: $!\n"; sleep 1; print STDOUT time%1000, ": polling child\n"; if (not datawaiting($child)) { ##### CHANGE +D print STDOUT time%1000, ": no input from child yet\n"; } else { my $line = <$child>; chomp $line; print STDOUT time%1000, ": received <$line>\n"; } } else { #child die "cannot fork: $!" unless defined $pid; close $child or die "close: $!\n"; print STDOUT time%1000, ": child started\n"; sleep 5; print {$parent} time%1000, ": child printed\n"; close $parent or die "close: $!\n"; exit; } sub datawaiting ####### CHANGED see perldoc -f select { my $rin = my $win = my $ein = ''; vec($rin, fileno(shift), 1) = 1; return scalar select my $rout = $rin, my $wout = $win, my $eout = $e +in, 0; }

    Outputs:

    277: child started 278: polling child 278: no input from child yet

    Is that what you were looking for ?

Re^3: eof() blocking
by tybalt89 (Monsignor) on Nov 05, 2020 at 15:51 UTC

    With IO::Select, this isn't too much to avoid, is it?

    #!/usr/bin/perl use diagnostics; use strict 'subs'; use strict 'refs'; use Socket; use IO::Handle; use IO::Select; #### ADDED my $child; #filehandle to child process my $parent; #filehandle to parent process my $pid; #Process ID of child process socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $! +"; $child->autoflush(1); $parent->autoflush(1); if ($pid = fork()) { #parent close $parent or die "close: $!\n"; sleep 1; print STDOUT time%1000, ": polling child\n"; if ( IO::Select->new($child)->can_read(0) ) { ############### CHA +NGE my $line = <$child>; chomp $line; print STDOUT time%1000, ": received <$line>\n"; } else { print STDOUT time%1000, ": no input from child yet\n"; } } else { #child die "cannot fork: $!" unless defined $pid; close $child or die "close: $!\n"; print STDOUT time%1000, ": child started\n"; sleep 5; print {$parent} time%1000, ": child printed\n"; close $parent or die "close: $!\n"; exit; }