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