Subject: | read loop hanging even when all handles are closed |
I'm running Perl 5.10.1 on FreeBSD 8.2 with IPC::Open3::Utils 0.8. I cannot duplicate this on Centos 5.4/Perl 5.8.8 (another
system I use with an equivalent setup) or older FreeBSD versions running 5.8.8.
I use run_cmd() like this:
IPC::Open3::Utils::run_cmd
(@ssh, $target, '/bin/sh',
{ autoflush => { stdout => 1,
stderr => 1,
stdin => 1 },
pre_read_print_to_stdin => $some_script,
close_stdin => 1,
});
run_cmd() never returns. I found by tracing the process it's stuck in the READ_LOOP block of run_cmd() in the call to $sel-
Show quoted text
>can_read. More tracing reveals it's hung in a call to Perl's select() while trying to see if there are any readable filehandles. While
both handles (stdout, stderr) have already been closed in run_cmd(), IO::Select is still trying to read them (there may be a
deeper bug here in IO::Select).
A workaround I found is to remove the defunct handles from the IO::Select object before closing them in run_cmd():
--- Utils.pm.orig 2010-05-21 15:50:29.000000000 +0100
+++ Utils.pm 2011-04-11 20:15:31.000000000 +0100
@@ -212,6 +212,7 @@
HANDLE:
for my $fh (@ready) {
if ( $fh->eof ) {
+ $sel->remove($fh);
$fh->close;
next HANDLE;
}
This technique is consistent with and recommended by IO::Select's documentation on how to deal with completed handles (see
IO::Select's EXAMPLE section).