Gregory Toomey said:
I need to combine pipe open + make it non-blocking. The semantics I want
are:
# based on perlopentut
open(NET, "ping 11.22.33.44 |", O_NONBLOCK ) || die "can't fork ping";
while (<NET>) { print }
close(NET)
which of course gets a syntax error.
Any idea how to achieve this?
Dear Greg,
To be able to read a command's output in a non-blocking manner, you
can use the IPC::Open2 module together with IO::Select. Here is a
sample program that pings 127.0.0.1:
#!/usr/bin/perl -w
use strict;
use IPC::Open2;
use IO::Select;
$| = 1; # autoflush STDOUT
# Declare filehandles and command to use:
my ($r, $w);
my $cmd = 'ping 127.0.0.1';
# Open the process and set the selector:
my $pid = open2($r, $w, $cmd);
my $selector = IO::Select->new($r);
sleep 1; # allow some time for request to process
# print out output from process, if any exists:
while ($selector->can_read(0))
{
my $char;
sysread($r, $char, 1);
print $char;
unless ($selector->can_read(0))
{
sleep 1; # allow some time for request to process
# or else while loop will finish if there
# there is a pause in the program
}
}
__END__
I basically use IO::Select with the can_read() method to tell when
output is waiting for me to read. Note that I periodically sleep for
some time in order to give the process enough time to output some
text. Without the sleep command, the while loop would exit as soon as
ping produces a pause (because technically there is nothing waiting to
be read during a pause).
This script should work on Unix, but I'm almost entirely sure it
won't work on Win32 platforms.
Hope this helps,
-- Jean-Luc