Perl select returning undef on sysread when using Windows, IPC::Open3, and IO::Socket->socketpair() -
i found this example (posted @ikegami) of way use ipc::open3 on windows using sockets. problem that, when run it, error an existing connection forcibly closed remote host on sysread
. command runs, select
works correctly, sysread
getting undef
instead of expected 0
end of file. behavior not same commands. if change command echo hello world!
not cause error. idea going on here?
here code example:
use strict; use warnings; use io::select qw( ); use ipc::open3 qw( open3 ); use socket qw( af_unix sock_stream pf_unspec ); print( "remove me: getting started\n" ); sub _pipe { socketpair($_[0], $_[1], af_unix, sock_stream, pf_unspec) or return undef; shutdown($_[0], 1); # no more writing reader shutdown($_[1], 0); # no more reading writer return 1; } sub _open3 { local (*to_chld_r, *to_chld_w); local (*fr_chld_r, *fr_chld_w); local (*fr_chld_err_r, *fr_chld_err_w); if ($^o =~ /win32/) { _pipe(*to_chld_r, *to_chld_w ) or die $^e; _pipe(*fr_chld_r, *fr_chld_w ) or die $^e; _pipe(*fr_chld_err_r, *fr_chld_err_w) or die $^e; } else { pipe(*to_chld_r, *to_chld_w ) or die $!; pipe(*fr_chld_r, *fr_chld_w ) or die $!; pipe(*fr_chld_err_r, *fr_chld_err_w) or die $!; } $pid = open3('>&to_chld_r', '<&fr_chld_w', '<&fr_chld_err_w', @_); return ( $pid, *to_chld_w, *fr_chld_r, *fr_chld_err_r ); } # when change command 'echo hello world' works... ($pid, $to_chld, $fr_chld, $fr_chld_err) = _open3('cmd /c "dir /s/b"'); %objs; $in_sel = io::select->new(); $out_sel = io::select->new(); $fh ($fr_chld, $fr_chld_err) { $obj = { buf => '', }; $objs{ fileno($fh) } = $obj; $in_sel->add($fh); } close($to_chld); while ($in_sel->count() + $out_sel->count()) { ($ins, $outs) = io::select::select($in_sel, $out_sel, undef); $fh (@$ins) { $obj = $objs{ fileno($fh) }; our $buf; local *buf = \( $obj->{buf} ); $bytes_read = sysread($fh, $buf, 64*1024, length($buf)); if (!$bytes_read) { warn("error reading child: $!\n") if !defined($bytes_read); $in_sel->remove($fh); } } $fh (@$outs) { } } waitpid($pid, 0); print("stdout:\n$objs{ fileno( $fr_chld ) }{buf}"); print("\n" ); print("stderr:\n$objs{ fileno( $fr_chld_err ) }{buf}");
i think it's because shutdown
used instead of close
. sounds safe ignore.
grep $!{$_}, keys %!
shows econnreset
, change
warn("error reading child: $!\n") if !defined($bytes_read);
to
warn("error reading child: $!\n") if !defined($bytes_read) && !$!{econnreset};
Comments
Post a Comment