I have a Perl script that uses an external tool (cleartool) to gather information about a list of files. I want to use IPC to avoid spawning a new process for each file:
use IPC::Open2;
my ($cin, $cout);
my $child = open2($cout, $cin, 'cleartool');
Commands that return single-lines work well. e.g.
print $cin "describe -short $file\n";
my $description = <$cout>;
Commands that return multiple lines have me at a dead end for how to consume the entire response without getting hung up by a blocking read:
print $cin "lshistory $file\n";
# read and process $cout...
I've tried to set the filehandle for non-blocking reads via fcntl
:
use Fcntl;
my $flags = '';
fcntl($cout, F_GETFL, $flags);
$flags |= O_NONBLOCK;
fcntl($cout, F_SETFL, $flags);
but Fcntl dies with the message "Your vendor has not defined Fcntl macro F_GETFL."
I've tried using IO::Handle to set $cout->blocking(0)
but that fails (it returns undef
and sets $!
to "Unknown error").
I've tried to use select
to determine if there's data available before attempting to read:
my $rfd = '';
vec($rfd, fileno($cout), 1) = 1;
while (select($rfd, undef, undef, 0) >= 0) {
my $n = read($cout, $buffer, 1024);
print "Read $n bytes\n";
# do something with $buffer...
}
but that hangs without ever reading anything. Does anyone know how to make this work (on Windows)?