Subject: | fhopen() broken in version 3.04 on MSWin32 systems |
I'm using both ActiveState Perl v5.16.3 and Strawberry Perl v5.18.2 on MSWin32-x86-multi-thread and I extensively use Net::Telnet but I open my own sockets either with either IO::Socket::INET or IO::Socket::IP.
This was working fine with Net::Telnet 3.03 but is broken with latest version 3.04.
This code snippet, which uses open(), works well with both 3.03 & 3.04 :
use Net::Telnet ();
print "Using Net::Telnet $Net::Telnet::VERSION\n";
$host = "<ip address>";
$telnet_timeout = 20;
$t = new Net::Telnet (Timeout => $telnet_timeout, Errmode => 'return');
$t->open($host);
print "Open done\n";
$output = $t->get or die $t->errmsg;
print $output, "\n";
$output = $t->get(Timeout => 0);
print "\nNon-blocking read >", $output, "<\n";
The output is respectively:
Using Net::Telnet 3.03
Open done
login:
Non-blocking read ><
and:
Using Net::Telnet 3.04
Open done
login:
Non-blocking read ><
This code snippet, which uses fhopen(), works well with 3.03 but fails with 3.04 :
use Net::Telnet ();
use IO::Socket::IP;
use IO::Socket::INET;
print "Using Net::Telnet $Net::Telnet::VERSION\n";
$host = "<ip address>";
$telnet_timeout = 20;
$connect_timeout = 15;
$t = new Net::Telnet (Timeout => $telnet_timeout, Errmode => 'return');
$sock = IO::Socket::INET->new(PeerHost => $host, PeerPort => 23, Timeout => $connect_timeout) or die "Unable to establish socket - $@";
#$sock = IO::Socket::IP->new(PeerHost => $host, PeerPort => 23, Blocking => 1) or die "Unable to establish socket - $@";
$t->fhopen($sock) or die $t->errmsg;
print "Open done\n";
$output = $t->get or die $t->errmsg;
print $output, "\n";
$output = $t->get(Timeout => 0); # Code gets stuck here with Net::Telnet 3.04
print "\nNon-blocking read >", $output, "<\n";
The output is respectively:
Using Net::Telnet 3.03
Open done
login:
Non-blocking read ><
and:
Using Net::Telnet 3.04
Open done
login:
Terminating on signal SIGINT(2) <== had to kill script with CTRL-C
Note that exactly the same happens if using IO::Socket::IP instead of IO::Socket::INET
This code snippet, which also uses fhopen(), works well with 3.03 but again fails with 3.04 :
use Net::Telnet ();
use IO::Socket::IP;
use Errno qw( EINPROGRESS EWOULDBLOCK );
print "Using Net::Telnet $Net::Telnet::VERSION\n";
$host = "<ip address>";
$telnet_timeout = 20;
$connect_timeout = 15;
$t = new Net::Telnet (Timeout => $telnet_timeout, Errmode => 'return');
$sock = IO::Socket::IP->new(PeerHost => $host, PeerPort => 23, Blocking => 0) or die "Unable to establish socket - $@";
while( !$sock->connect && ( $! == EINPROGRESS || $! == EWOULDBLOCK ) ) {
my $wvec = '';
vec( $wvec, fileno $sock, 1 ) = 1;
my $evec = '';
vec( $evec, fileno $sock, 1 ) = 1;
select( undef, $wvec, $evec, $connect_timeout ) or die "Connection timeout expired";
}
die "Unable to connect - $!" if $!;
$t->fhopen($sock) or die $t->errmsg;
print "Open done\n";
$output = $t->get or die $t->errmsg; # with Net::Telnet 3.04, dies with error: A non-blocking socket operation could not be completed immediately
print $output, "\n";
$output = $t->get(Timeout => 0);
print "\nNon-blocking read >", $output, "<\n";
The output is respectively:
Using Net::Telnet 3.03
Open done
login:
Non-blocking read ><
and:
Using Net::Telnet 3.04
Open done
read error: A non-blocking socket operation could not be completed immediately. at net-telnet-test3.pl line 24.
The problem is related to line 710 of Net::Telnet 3.04 :
$s->{select_supported} = $^O ne "MSWin32" || -S $self;
This line gets executed by fhopen() and always sets object hash key select_supported to false on Windows systems.
In particular the -S file test operator to check if the filehandle is a socket does not appear to work on Windows systems. So perhaps the above line should be replaced with:
$s->{select_supported} = $^O eq "MSWin32" || -S $self;
As a workaround, I can get my code to work again on the newer 3.04 Net::Telnet if I add this line immediately after the fhopen():
$t->fhopen($sock) or die $t->errmsg;
(*$t->{net_telnet})->{select_supported} = 1;