use strict;
our(@ISA, $VERSION);
use Exporter;
+use Errno;
# legacy
@ISA = qw(IO::Handle);
-$VERSION = "1.252";
+$VERSION = "1.26";
sub import {
my $pkg = shift;
my $sock = shift;
my $addr = shift;
my $timeout = ${*$sock}{'io_socket_timeout'};
-
+ my $err;
my $blocking;
$blocking = $sock->blocking(0) if $timeout;
- eval {
- croak 'connect: Bad address'
- if(@_ == 2 && !defined $_[1]);
-
- unless(connect($sock, $addr)) {
- if($timeout && ($! == &IO::EINPROGRESS)) {
- require IO::Select;
+ if (!connect($sock, $addr)) {
+ if ($timeout && exists(&IO::EINPROGRESS) && ($! == &IO::EINPROGRESS)) {
+ require IO::Select;
- my $sel = new IO::Select $sock;
+ my $sel = new IO::Select $sock;
- unless($sel->can_write($timeout) && defined($sock->peername)) {
- croak "connect: timeout";
- }
+ if (!$sel->can_write($timeout)) {
+ $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
+ $@ = "connect: timeout";
}
- else {
- croak "connect: $!";
+ elsif(!connect($sock,$addr)) {
+ $err = $!;
+ $@ = "connect: $!";
}
}
- };
+ else {
+ $err = $!;
+ $@ = "connect: $!";
+ }
+ }
- my $ret = $@ ? undef : $sock;
+ $sock->blocking(1) if $blocking;
- $sock->blocking($blocking) if $timeout;
+ $! = $err if $err;
- $ret;
+ $err ? undef : $sock;
}
sub bind {
my $new = $pkg->new(Timeout => $timeout);
my $peer = undef;
- eval {
- if($timeout) {
- require IO::Select;
+ if($timeout) {
+ require IO::Select;
- my $sel = new IO::Select $sock;
+ my $sel = new IO::Select $sock;
+
+ unless ($sel->can_read($timeout)) {
+ $@ = 'accept: timeout';
+ $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
+ return;
+ }
+ }
+
+ $peer = accept($new,$sock)
+ or return;
- croak "accept: timeout"
- unless $sel->can_read($timeout);
- }
- $peer = accept($new,$sock) || undef;
- };
- croak "$@" if $@ and $sock;
-
- return wantarray ? defined $peer ? ($new, $peer)
- : ()
- : defined $peer ? $new
- : undef;
+ return wantarray ? ($new, $peer)
+ : $new;
}
sub sockname {
use Socket;
use Carp;
use Exporter;
+use Errno qw(EINVAL); # EINVAL appears portable
@ISA = qw(IO::Socket);
-$VERSION = "1.24";
+$VERSION = "1.25";
IO::Socket::INET->register_domain( AF_INET );
if(defined $addr && $addr =~ s,:([\w\(\)/]+)$,,);
if(defined $proto) {
- @proto = $proto =~ m,\D, ? getprotobyname($proto)
- : getprotobynumber($proto);
-
- $proto = $proto[2] || undef;
+ if (@proto = ( $proto =~ m,\D,
+ ? getprotobyname($proto)
+ : getprotobynumber($proto))
+ ) {
+ $proto = $proto[2] || undef;
+ }
+ else {
+ $@ = "Bad protocol '$proto'";
+ return;
+ }
}
if(defined $port) {
my $defport = $1 || undef;
my $pnum = ($port =~ m,^(\d+)$,)[0];
- @serv= getservbyname($port, $proto[0] || "")
- if($port =~ m,\D,);
+ if ($port =~ m,\D,) {
+ unless (@serv = getservbyname($port, $proto[0] || "")) {
+ $@ = "Bad service '$port'";
+ return;
+ }
+ }
$port = $pnum || $serv[2] || $defport || undef;
sub _error {
my $sock = shift;
- local($!);
- $@ = join("",ref($sock),": ",@_);
- close($sock)
+ my $err = shift;
+ {
+ local($!);
+ $@ = join("",ref($sock),": ",@_);
+ close($sock)
if(defined fileno($sock));
+ }
+ $! = $err;
return undef;
}
($laddr,$lport,$proto) = _sock_info($arg->{LocalAddr},
$arg->{LocalPort},
- $arg->{Proto});
+ $arg->{Proto})
+ or return _error($sock, $!, $@);
$laddr = defined $laddr ? inet_aton($laddr)
: INADDR_ANY;
- return _error($sock,"Bad hostname '",$arg->{LocalAddr},"'")
+ return _error($sock, EINVAL, "Bad hostname '",$arg->{LocalAddr},"'")
unless(defined $laddr);
$arg->{PeerAddr} = $arg->{PeerHost}
unless(exists $arg->{Listen}) {
($raddr,$rport,$proto) = _sock_info($arg->{PeerAddr},
$arg->{PeerPort},
- $proto);
+ $proto)
+ or return _error($sock, $!, $@);
}
$proto ||= (getprotobyname('tcp'))[2];
if(defined $raddr) {
@raddr = $sock->_get_addr($raddr, $arg->{MultiHomed});
- return _error($sock,"Bad hostname '",$arg->{PeerAddr},"'")
+ return _error($sock, EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
unless @raddr;
}
while(1) {
$sock->socket(AF_INET, $type, $proto) or
- return _error($sock,"$!");
+ return _error($sock, $!, "$!");
if ($arg->{Reuse}) {
$sock->sockopt(SO_REUSEADDR,1) or
- return _error($sock,"$!");
+ return _error($sock, $!, "$!");
}
if($lport || ($laddr ne INADDR_ANY) || exists $arg->{Listen}) {
$sock->bind($lport || 0, $laddr) or
- return _error($sock,"$!");
+ return _error($sock, $!, "$!");
}
if(exists $arg->{Listen}) {
$sock->listen($arg->{Listen} || 5) or
- return _error($sock,"$!");
+ return _error($sock, $!, "$!");
last;
}
$raddr = shift @raddr;
- return _error($sock,'Cannot determine remote port')
+ return _error($sock, EINVAL, 'Cannot determine remote port')
unless($rport || $type == SOCK_DGRAM || $type == SOCK_RAW);
last
unless($type == SOCK_STREAM || defined $raddr);
- return _error($sock,"Bad hostname '",$arg->{PeerAddr},"'")
+ return _error($sock, EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
unless defined $raddr;
# my $timeout = ${*$sock}{'io_socket_timeout'};
return $sock;
}
- return _error($sock,"$!")
+ return _error($sock, $!, "Timeout")
unless @raddr;
# if ($timeout) {
# my $new_timeout = $timeout - (time() - $before);
-# return _error($sock, "Timeout") if $new_timeout <= 0;
+# return _error($sock,
+# (exists(&Errno::ETIMEDOUT) ? &Errno::ETIMEDOUT : EINVAL),
+# "Timeout") if $new_timeout <= 0;
# ${*$sock}{'io_socket_timeout'} = $new_timeout;
# }