| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 |  |  |  |  |  |  | # IO::Socket.pm | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | # Copyright (c) 1997-8 Graham Barr . All rights reserved. | 
| 5 |  |  |  |  |  |  | # This program is free software; you can redistribute it and/or | 
| 6 |  |  |  |  |  |  | # modify it under the same terms as Perl itself. | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | package IO::Socket; | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 17 |  |  | 17 |  | 77244 | use 5.008_001; | 
|  | 17 |  |  |  |  | 131 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 17 |  |  | 17 |  | 5796 | use IO::Handle; | 
|  | 17 |  |  |  |  | 71 |  | 
|  | 17 |  |  |  |  | 884 |  | 
| 13 | 17 |  |  | 17 |  | 6727 | use Socket 1.3; | 
|  | 17 |  |  |  |  | 55862 |  | 
|  | 17 |  |  |  |  | 6048 |  | 
| 14 | 17 |  |  | 17 |  | 139 | use Carp; | 
|  | 17 |  |  |  |  | 26 |  | 
|  | 17 |  |  |  |  | 716 |  | 
| 15 | 17 |  |  | 17 |  | 82 | use strict; | 
|  | 17 |  |  |  |  | 33 |  | 
|  | 17 |  |  |  |  | 302 |  | 
| 16 | 17 |  |  | 17 |  | 69 | use Exporter; | 
|  | 17 |  |  |  |  | 26 |  | 
|  | 17 |  |  |  |  | 433 |  | 
| 17 | 17 |  |  | 17 |  | 4960 | use Errno; | 
|  | 17 |  |  |  |  | 17357 |  | 
|  | 17 |  |  |  |  | 15984 |  | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | # legacy | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | require IO::Socket::INET; | 
| 22 |  |  |  |  |  |  | require IO::Socket::UNIX if ($^O ne 'epoc' && $^O ne 'symbian'); | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | our @ISA = qw(IO::Handle); | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | our $VERSION = "1.49"; | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | our @EXPORT_OK = qw(sockatmark); | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | our $errstr; | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | sub import { | 
| 33 | 54 |  |  | 54 |  | 191 | my $pkg = shift; | 
| 34 | 54 | 50 | 66 |  |  | 211 | if (@_ && $_[0] eq 'sockatmark') { # not very extensible but for now, fast | 
| 35 | 0 |  |  |  |  | 0 | Exporter::export_to_level('IO::Socket', 1, $pkg, 'sockatmark'); | 
| 36 |  |  |  |  |  |  | } else { | 
| 37 | 54 |  |  |  |  | 106 | my $callpkg = caller; | 
| 38 | 54 |  |  |  |  | 41459 | Exporter::export 'Socket', $callpkg, @_; | 
| 39 |  |  |  |  |  |  | } | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | sub new { | 
| 43 | 62 |  |  | 62 | 1 | 1001414 | my($class,%arg) = @_; | 
| 44 | 62 |  |  |  |  | 886 | my $sock = $class->SUPER::new(); | 
| 45 |  |  |  |  |  |  |  | 
| 46 | 62 |  |  |  |  | 898 | $sock->autoflush(1); | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 62 |  |  |  |  | 748 | ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout}; | 
|  | 62 |  |  |  |  | 461 |  | 
| 49 |  |  |  |  |  |  |  | 
| 50 | 62 | 100 |  |  |  | 671 | return scalar(%arg) ? $sock->configure(\%arg) | 
| 51 |  |  |  |  |  |  | : $sock; | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | my @domain2pkg; | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | sub register_domain { | 
| 57 | 34 |  |  | 34 | 0 | 95 | my($p,$d) = @_; | 
| 58 | 34 |  |  |  |  | 95 | $domain2pkg[$d] = $p; | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | sub configure { | 
| 62 | 4 |  |  | 4 | 0 | 47 | my($sock,$arg) = @_; | 
| 63 | 4 |  |  |  |  | 27 | my $domain = delete $arg->{Domain}; | 
| 64 |  |  |  |  |  |  |  | 
| 65 | 4 | 50 |  |  |  | 34 | croak 'IO::Socket: Cannot configure a generic socket' | 
| 66 |  |  |  |  |  |  | unless defined $domain; | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 4 | 50 |  |  |  | 55 | croak "IO::Socket: Unsupported socket domain" | 
| 69 |  |  |  |  |  |  | unless defined $domain2pkg[$domain]; | 
| 70 |  |  |  |  |  |  |  | 
| 71 | 4 | 50 |  |  |  | 32 | croak "IO::Socket: Cannot configure socket in domain '$domain'" | 
| 72 |  |  |  |  |  |  | unless ref($sock) eq "IO::Socket"; | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 4 |  |  |  |  | 25 | bless($sock, $domain2pkg[$domain]); | 
| 75 | 4 |  |  |  |  | 67 | $sock->configure($arg); | 
| 76 |  |  |  |  |  |  | } | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub socket { | 
| 79 | 43 | 50 |  | 43 | 1 | 161 | @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)'; | 
| 80 | 43 |  |  |  |  | 133 | my($sock,$domain,$type,$protocol) = @_; | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 43 | 50 |  |  |  | 2012 | socket($sock,$domain,$type,$protocol) or | 
| 83 |  |  |  |  |  |  | return undef; | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 43 |  |  |  |  | 118 | ${*$sock}{'io_socket_domain'} = $domain; | 
|  | 43 |  |  |  |  | 329 |  | 
| 86 | 43 |  |  |  |  | 127 | ${*$sock}{'io_socket_type'}   = $type; | 
|  | 43 |  |  |  |  | 115 |  | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | # "A value of 0 for protocol will let the system select an | 
| 89 |  |  |  |  |  |  | # appropriate protocol" | 
| 90 |  |  |  |  |  |  | # so we need to look up what the system selected, | 
| 91 |  |  |  |  |  |  | # not cache PF_UNSPEC. | 
| 92 | 43 | 100 |  |  |  | 115 | ${*$sock}{'io_socket_proto'} = $protocol if $protocol; | 
|  | 36 |  |  |  |  | 152 |  | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 43 |  |  |  |  | 170 | $sock; | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | sub socketpair { | 
| 98 | 0 | 0 |  | 0 | 1 | 0 | @_ == 4 || croak 'usage: IO::Socket->socketpair(DOMAIN, TYPE, PROTOCOL)'; | 
| 99 | 0 |  |  |  |  | 0 | my($class,$domain,$type,$protocol) = @_; | 
| 100 | 0 |  |  |  |  | 0 | my $sock1 = $class->new(); | 
| 101 | 0 |  |  |  |  | 0 | my $sock2 = $class->new(); | 
| 102 |  |  |  |  |  |  |  | 
| 103 | 0 | 0 |  |  |  | 0 | socketpair($sock1,$sock2,$domain,$type,$protocol) or | 
| 104 |  |  |  |  |  |  | return (); | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 0 |  |  |  |  | 0 | ${*$sock1}{'io_socket_type'}  = ${*$sock2}{'io_socket_type'}  = $type; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 107 | 0 |  |  |  |  | 0 | ${*$sock1}{'io_socket_proto'} = ${*$sock2}{'io_socket_proto'} = $protocol; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 108 |  |  |  |  |  |  |  | 
| 109 | 0 |  |  |  |  | 0 | ($sock1,$sock2); | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | sub connect { | 
| 113 | 13 | 50 |  | 13 | 0 | 69 | @_ == 2 or croak 'usage: $sock->connect(NAME)'; | 
| 114 | 13 |  |  |  |  | 45 | my $sock = shift; | 
| 115 | 13 |  |  |  |  | 47 | my $addr = shift; | 
| 116 | 13 |  |  |  |  | 35 | my $timeout = ${*$sock}{'io_socket_timeout'}; | 
|  | 13 |  |  |  |  | 78 |  | 
| 117 | 13 |  |  |  |  | 35 | my $err; | 
| 118 |  |  |  |  |  |  | my $blocking; | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 13 | 100 |  |  |  | 64 | $blocking = $sock->blocking(0) if $timeout; | 
| 121 | 13 | 100 |  |  |  | 1485 | if (!connect($sock, $addr)) { | 
| 122 | 1 | 50 | 33 |  |  | 47 | if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) { | 
|  |  | 0 | 33 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
| 123 | 1 |  |  |  |  | 936 | require IO::Select; | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 1 |  |  |  |  | 6 | my $sel = IO::Select->new( $sock ); | 
| 126 |  |  |  |  |  |  |  | 
| 127 | 1 |  |  |  |  | 3 | undef $!; | 
| 128 | 1 |  |  |  |  | 3 | my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout); | 
| 129 | 1 | 50 | 33 |  |  | 32 | if(@$e[0]) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | # Windows return from select after the timeout in case of | 
| 131 |  |  |  |  |  |  | # WSAECONNREFUSED(10061) if exception set is not used. | 
| 132 |  |  |  |  |  |  | # This behavior is different from Linux. | 
| 133 |  |  |  |  |  |  | # Using the exception | 
| 134 |  |  |  |  |  |  | # set we now emulate the behavior in Linux | 
| 135 |  |  |  |  |  |  | #    - Karthik Rajagopalan | 
| 136 | 0 |  |  |  |  | 0 | $err = $sock->getsockopt(SOL_SOCKET,SO_ERROR); | 
| 137 | 0 |  |  |  |  | 0 | $errstr = $@ = "connect: $err"; | 
| 138 |  |  |  |  |  |  | } | 
| 139 |  |  |  |  |  |  | elsif(!@$w[0]) { | 
| 140 | 0 |  | 0 |  |  | 0 | $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1); | 
| 141 | 0 |  |  |  |  | 0 | $errstr = $@ = "connect: timeout"; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  | elsif (!connect($sock,$addr) && | 
| 144 |  |  |  |  |  |  | not ($!{EISCONN} || ($^O eq 'MSWin32' && | 
| 145 |  |  |  |  |  |  | ($! == (($] < 5.019004) ? 10022 : Errno::EINVAL)))) | 
| 146 |  |  |  |  |  |  | ) { | 
| 147 |  |  |  |  |  |  | # Some systems refuse to re-connect() to | 
| 148 |  |  |  |  |  |  | # an already open socket and set errno to EISCONN. | 
| 149 |  |  |  |  |  |  | # Windows sets errno to WSAEINVAL (10022) (pre-5.19.4) or | 
| 150 |  |  |  |  |  |  | # EINVAL (22) (5.19.4 onwards). | 
| 151 | 0 |  |  |  |  | 0 | $err = $!; | 
| 152 | 0 |  |  |  |  | 0 | $errstr = $@ = "connect: $!"; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  | elsif ($blocking || !($!{EINPROGRESS} || $!{EWOULDBLOCK}))  { | 
| 156 | 0 |  |  |  |  | 0 | $err = $!; | 
| 157 | 0 |  |  |  |  | 0 | $errstr = $@ = "connect: $!"; | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  |  | 
| 161 | 13 | 100 |  |  |  | 71 | $sock->blocking(1) if $blocking; | 
| 162 |  |  |  |  |  |  |  | 
| 163 | 13 | 50 |  |  |  | 45 | $! = $err if $err; | 
| 164 |  |  |  |  |  |  |  | 
| 165 | 13 | 50 |  |  |  | 131 | $err ? undef : $sock; | 
| 166 |  |  |  |  |  |  | } | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | # Enable/disable blocking IO on sockets. | 
| 169 |  |  |  |  |  |  | # Without args return the current status of blocking, | 
| 170 |  |  |  |  |  |  | # with args change the mode as appropriate, returning the | 
| 171 |  |  |  |  |  |  | # old setting, or in case of error during the mode change | 
| 172 |  |  |  |  |  |  | # undef. | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | sub blocking { | 
| 175 | 10 |  |  | 10 | 1 | 247 | my $sock = shift; | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 10 | 50 | 33 |  |  | 335 | return $sock->SUPER::blocking(@_) | 
| 178 |  |  |  |  |  |  | if $^O ne 'MSWin32' && $^O ne 'VMS'; | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | # Windows handles blocking differently | 
| 181 |  |  |  |  |  |  | # | 
| 182 |  |  |  |  |  |  | # http://groups.google.co.uk/group/perl.perl5.porters/browse_thread/thread/b4e2b1d88280ddff/630b667a66e3509f?#630b667a66e3509f | 
| 183 |  |  |  |  |  |  | # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ioctlsocket_2.asp | 
| 184 |  |  |  |  |  |  | # | 
| 185 |  |  |  |  |  |  | # 0x8004667e is FIONBIO | 
| 186 |  |  |  |  |  |  | # | 
| 187 |  |  |  |  |  |  | # which is used to set blocking behaviour. | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | # NOTE: | 
| 190 |  |  |  |  |  |  | # This is a little confusing, the perl keyword for this is | 
| 191 |  |  |  |  |  |  | # 'blocking' but the OS level behaviour is 'non-blocking', probably | 
| 192 |  |  |  |  |  |  | # because sockets are blocking by default. | 
| 193 |  |  |  |  |  |  | # Therefore internally we have to reverse the semantics. | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 0 |  |  |  |  | 0 | my $orig= !${*$sock}{io_sock_nonblocking}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 196 |  |  |  |  |  |  |  | 
| 197 | 0 | 0 |  |  |  | 0 | return $orig unless @_; | 
| 198 |  |  |  |  |  |  |  | 
| 199 | 0 |  |  |  |  | 0 | my $block = shift; | 
| 200 |  |  |  |  |  |  |  | 
| 201 | 0 | 0 |  |  |  | 0 | if ( !$block != !$orig ) { | 
| 202 | 0 | 0 |  |  |  | 0 | ${*$sock}{io_sock_nonblocking} = $block ? 0 : 1; | 
|  | 0 |  |  |  |  | 0 |  | 
| 203 | 0 | 0 |  |  |  | 0 | ioctl($sock, 0x8004667e, pack("L!",${*$sock}{io_sock_nonblocking})) | 
|  | 0 |  |  |  |  | 0 |  | 
| 204 |  |  |  |  |  |  | or return undef; | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  |  | 
| 207 | 0 |  |  |  |  | 0 | return $orig; | 
| 208 |  |  |  |  |  |  | } | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | sub close { | 
| 212 | 19 | 50 |  | 19 | 0 | 2582012 | @_ == 1 or croak 'usage: $sock->close()'; | 
| 213 | 19 |  |  |  |  | 48 | my $sock = shift; | 
| 214 | 19 |  |  |  |  | 42 | ${*$sock}{'io_socket_peername'} = undef; | 
|  | 19 |  |  |  |  | 218 |  | 
| 215 | 19 |  |  |  |  | 292 | $sock->SUPER::close(); | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | sub bind { | 
| 219 | 28 | 50 |  | 28 | 1 | 110 | @_ == 2 or croak 'usage: $sock->bind(NAME)'; | 
| 220 | 28 |  |  |  |  | 52 | my $sock = shift; | 
| 221 | 28 |  |  |  |  | 106 | my $addr = shift; | 
| 222 |  |  |  |  |  |  |  | 
| 223 | 28 | 50 |  |  |  | 845 | return bind($sock, $addr) ? $sock | 
| 224 |  |  |  |  |  |  | : undef; | 
| 225 |  |  |  |  |  |  | } | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | sub listen { | 
| 228 | 20 | 50 | 33 | 20 | 1 | 169 | @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])'; | 
| 229 | 20 |  |  |  |  | 69 | my($sock,$queue) = @_; | 
| 230 | 20 | 50 | 33 |  |  | 239 | $queue = 5 | 
| 231 |  |  |  |  |  |  | unless $queue && $queue > 0; | 
| 232 |  |  |  |  |  |  |  | 
| 233 | 20 | 50 |  |  |  | 328 | return listen($sock, $queue) ? $sock | 
| 234 |  |  |  |  |  |  | : undef; | 
| 235 |  |  |  |  |  |  | } | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | sub accept { | 
| 238 | 21 | 50 | 33 | 21 | 1 | 3020089 | @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])'; | 
| 239 | 21 |  |  |  |  | 306 | my $sock = shift; | 
| 240 | 21 |  | 33 |  |  | 344 | my $pkg = shift || $sock; | 
| 241 | 21 |  |  |  |  | 52 | my $timeout = ${*$sock}{'io_socket_timeout'}; | 
|  | 21 |  |  |  |  | 445 |  | 
| 242 | 21 |  |  |  |  | 474 | my $new = $pkg->new(Timeout => $timeout); | 
| 243 | 21 |  |  |  |  | 102 | my $peer = undef; | 
| 244 |  |  |  |  |  |  |  | 
| 245 | 21 | 100 |  |  |  | 103 | if(defined $timeout) { | 
| 246 | 18 |  |  |  |  | 6034 | require IO::Select; | 
| 247 |  |  |  |  |  |  |  | 
| 248 | 18 |  |  |  |  | 196 | my $sel = IO::Select->new( $sock ); | 
| 249 |  |  |  |  |  |  |  | 
| 250 | 18 | 100 |  |  |  | 123 | unless ($sel->can_read($timeout)) { | 
| 251 | 1 |  |  |  |  | 105 | $errstr = $@ = 'accept: timeout'; | 
| 252 | 1 | 50 |  |  |  | 69 | $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1); | 
| 253 | 1 |  |  |  |  | 32 | return; | 
| 254 |  |  |  |  |  |  | } | 
| 255 |  |  |  |  |  |  | } | 
| 256 |  |  |  |  |  |  |  | 
| 257 | 20 | 50 |  |  |  | 2001817 | $peer = accept($new,$sock) | 
| 258 |  |  |  |  |  |  | or return; | 
| 259 |  |  |  |  |  |  |  | 
| 260 | 20 |  |  |  |  | 144 | ${*$new}{$_} = ${*$sock}{$_} for qw( io_socket_domain io_socket_type io_socket_proto ); | 
|  | 60 |  |  |  |  | 611 |  | 
|  | 60 |  |  |  |  | 244 |  | 
| 261 |  |  |  |  |  |  |  | 
| 262 | 20 | 50 |  |  |  | 154 | return wantarray ? ($new, $peer) | 
| 263 |  |  |  |  |  |  | : $new; | 
| 264 |  |  |  |  |  |  | } | 
| 265 |  |  |  |  |  |  |  | 
| 266 |  |  |  |  |  |  | sub sockname { | 
| 267 | 25 | 50 |  | 25 | 1 | 278 | @_ == 1 or croak 'usage: $sock->sockname()'; | 
| 268 | 25 |  |  |  |  | 343 | getsockname($_[0]); | 
| 269 |  |  |  |  |  |  | } | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | sub peername { | 
| 272 | 2 | 50 |  | 2 | 1 | 15 | @_ == 1 or croak 'usage: $sock->peername()'; | 
| 273 | 2 |  |  |  |  | 4 | my($sock) = @_; | 
| 274 | 2 |  | 33 |  |  | 2 | ${*$sock}{'io_socket_peername'} ||= getpeername($sock); | 
|  | 2 |  |  |  |  | 20 |  | 
| 275 |  |  |  |  |  |  | } | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | sub connected { | 
| 278 | 2 | 50 |  | 2 | 1 | 43 | @_ == 1 or croak 'usage: $sock->connected()'; | 
| 279 | 2 |  |  |  |  | 5 | my($sock) = @_; | 
| 280 | 2 |  |  |  |  | 51 | getpeername($sock); | 
| 281 |  |  |  |  |  |  | } | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | sub send { | 
| 284 | 6 | 50 | 33 | 6 | 1 | 1000323 | @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])'; | 
| 285 | 6 |  |  |  |  | 14 | my $sock  = $_[0]; | 
| 286 | 6 |  | 50 |  |  | 30 | my $flags = $_[2] || 0; | 
| 287 | 6 |  |  |  |  | 11 | my $peer; | 
| 288 |  |  |  |  |  |  |  | 
| 289 | 6 | 100 |  |  |  | 94 | if ($_[3]) { | 
|  |  | 100 |  |  |  |  |  | 
| 290 |  |  |  |  |  |  | # the caller explicitly requested a TO, so use it | 
| 291 |  |  |  |  |  |  | # this is non-portable for "connected" UDP sockets | 
| 292 | 2 |  |  |  |  | 3 | $peer = $_[3]; | 
| 293 |  |  |  |  |  |  | } | 
| 294 |  |  |  |  |  |  | elsif (!defined getpeername($sock)) { | 
| 295 |  |  |  |  |  |  | # we're not connected, so we require a peer from somewhere | 
| 296 | 1 |  |  |  |  | 15 | $peer = $sock->peername; | 
| 297 |  |  |  |  |  |  |  | 
| 298 | 1 | 50 |  |  |  | 3 | croak 'send: Cannot determine peer address' | 
| 299 |  |  |  |  |  |  | unless(defined $peer); | 
| 300 |  |  |  |  |  |  | } | 
| 301 |  |  |  |  |  |  |  | 
| 302 | 6 | 100 |  |  |  | 231 | my $r = $peer | 
| 303 |  |  |  |  |  |  | ? send($sock, $_[1], $flags, $peer) | 
| 304 |  |  |  |  |  |  | : send($sock, $_[1], $flags); | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | # remember who we send to, if it was successful | 
| 307 | 6 | 100 | 66 |  |  | 40 | ${*$sock}{'io_socket_peername'} = $peer | 
|  | 2 |  |  |  |  | 13 |  | 
| 308 |  |  |  |  |  |  | if(@_ == 4 && defined $r); | 
| 309 |  |  |  |  |  |  |  | 
| 310 | 6 |  |  |  |  | 22 | $r; | 
| 311 |  |  |  |  |  |  | } | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | sub recv { | 
| 314 | 6 | 50 | 33 | 6 | 1 | 2550 | @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])'; | 
| 315 | 6 |  |  |  |  | 35 | my $sock  = $_[0]; | 
| 316 | 6 |  |  |  |  | 11 | my $len   = $_[2]; | 
| 317 | 6 |  | 50 |  |  | 63 | my $flags = $_[3] || 0; | 
| 318 |  |  |  |  |  |  |  | 
| 319 |  |  |  |  |  |  | # remember who we recv'd from | 
| 320 | 6 |  |  |  |  | 3728 | ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags); | 
|  | 6 |  |  |  |  | 94 |  | 
| 321 |  |  |  |  |  |  | } | 
| 322 |  |  |  |  |  |  |  | 
| 323 |  |  |  |  |  |  | sub shutdown { | 
| 324 | 0 | 0 |  | 0 | 1 | 0 | @_ == 2 or croak 'usage: $sock->shutdown(HOW)'; | 
| 325 | 0 |  |  |  |  | 0 | my($sock, $how) = @_; | 
| 326 | 0 |  |  |  |  | 0 | ${*$sock}{'io_socket_peername'} = undef; | 
|  | 0 |  |  |  |  | 0 |  | 
| 327 | 0 |  |  |  |  | 0 | shutdown($sock, $how); | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | sub setsockopt { | 
| 331 | 0 | 0 |  | 0 | 1 | 0 | @_ == 4 or croak '$sock->setsockopt(LEVEL, OPTNAME, OPTVAL)'; | 
| 332 | 0 |  |  |  |  | 0 | setsockopt($_[0],$_[1],$_[2],$_[3]); | 
| 333 |  |  |  |  |  |  | } | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  | my $intsize = length(pack("i",0)); | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | sub getsockopt { | 
| 338 | 13 | 50 |  | 13 | 1 | 37 | @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)'; | 
| 339 | 13 |  |  |  |  | 127 | my $r = getsockopt($_[0],$_[1],$_[2]); | 
| 340 |  |  |  |  |  |  | # Just a guess | 
| 341 | 13 | 50 | 33 |  |  | 116 | $r = unpack("i", $r) | 
| 342 |  |  |  |  |  |  | if(defined $r && length($r) == $intsize); | 
| 343 | 13 |  |  |  |  | 32 | $r; | 
| 344 |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  | 
| 346 |  |  |  |  |  |  | sub sockopt { | 
| 347 | 13 |  |  | 13 | 1 | 1443 | my $sock = shift; | 
| 348 | 13 | 50 |  |  |  | 84 | @_ == 1 ? $sock->getsockopt(SOL_SOCKET,@_) | 
| 349 |  |  |  |  |  |  | : $sock->setsockopt(SOL_SOCKET,@_); | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | sub atmark { | 
| 353 | 0 | 0 |  | 0 | 1 | 0 | @_ == 1 or croak 'usage: $sock->atmark()'; | 
| 354 | 0 |  |  |  |  | 0 | my($sock) = @_; | 
| 355 | 0 |  |  |  |  | 0 | sockatmark($sock); | 
| 356 |  |  |  |  |  |  | } | 
| 357 |  |  |  |  |  |  |  | 
| 358 |  |  |  |  |  |  | sub timeout { | 
| 359 | 0 | 0 | 0 | 0 | 1 | 0 | @_ == 1 || @_ == 2 or croak 'usage: $sock->timeout([VALUE])'; | 
| 360 | 0 |  |  |  |  | 0 | my($sock,$val) = @_; | 
| 361 | 0 |  |  |  |  | 0 | my $r = ${*$sock}{'io_socket_timeout'}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 362 |  |  |  |  |  |  |  | 
| 363 | 0 | 0 |  |  |  | 0 | ${*$sock}{'io_socket_timeout'} = defined $val ? 0 + $val : $val | 
|  | 0 | 0 |  |  |  | 0 |  | 
| 364 |  |  |  |  |  |  | if(@_ == 2); | 
| 365 |  |  |  |  |  |  |  | 
| 366 | 0 |  |  |  |  | 0 | $r; | 
| 367 |  |  |  |  |  |  | } | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | sub sockdomain { | 
| 370 | 10 | 50 |  | 10 | 1 | 2239 | @_ == 1 or croak 'usage: $sock->sockdomain()'; | 
| 371 | 10 |  |  |  |  | 26 | my $sock = shift; | 
| 372 | 10 | 100 |  |  |  | 16 | if (!defined(${*$sock}{'io_socket_domain'})) { | 
|  | 10 |  |  |  |  | 49 |  | 
| 373 | 2 |  |  |  |  | 23 | my $addr = $sock->sockname(); | 
| 374 | 2 | 50 |  |  |  | 18 | ${*$sock}{'io_socket_domain'} = sockaddr_family($addr) | 
|  | 2 |  |  |  |  | 9 |  | 
| 375 |  |  |  |  |  |  | if (defined($addr)); | 
| 376 |  |  |  |  |  |  | } | 
| 377 | 10 |  |  |  |  | 20 | ${*$sock}{'io_socket_domain'}; | 
|  | 10 |  |  |  |  | 69 |  | 
| 378 |  |  |  |  |  |  | } | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | sub socktype { | 
| 381 | 10 | 50 |  | 10 | 1 | 2062 | @_ == 1 or croak 'usage: $sock->socktype()'; | 
| 382 | 10 |  |  |  |  | 20 | my $sock = shift; | 
| 383 | 2 |  |  |  |  | 10 | ${*$sock}{'io_socket_type'} = $sock->sockopt(Socket::SO_TYPE) | 
| 384 | 10 | 100 | 66 |  |  | 16 | if (!defined(${*$sock}{'io_socket_type'}) && defined(eval{Socket::SO_TYPE})); | 
|  | 10 |  |  |  |  | 75 |  | 
|  | 2 |  |  |  |  | 14 |  | 
| 385 | 10 |  |  |  |  | 20 | ${*$sock}{'io_socket_type'} | 
|  | 10 |  |  |  |  | 41 |  | 
| 386 |  |  |  |  |  |  | } | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | sub protocol { | 
| 389 | 10 | 50 |  | 10 | 1 | 1725 | @_ == 1 or croak 'usage: $sock->protocol()'; | 
| 390 | 10 |  |  |  |  | 24 | my($sock) = @_; | 
| 391 | 5 |  |  |  |  | 15 | ${*$sock}{'io_socket_proto'} = $sock->sockopt(Socket::SO_PROTOCOL) | 
| 392 | 10 | 100 | 66 |  |  | 17 | if (!defined(${*$sock}{'io_socket_proto'}) && defined(eval{Socket::SO_PROTOCOL})); | 
|  | 10 |  |  |  |  | 78 |  | 
|  | 5 |  |  |  |  | 31 |  | 
| 393 | 10 |  |  |  |  | 23 | ${*$sock}{'io_socket_proto'}; | 
|  | 10 |  |  |  |  | 49 |  | 
| 394 |  |  |  |  |  |  | } | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | 1; | 
| 397 |  |  |  |  |  |  |  | 
| 398 |  |  |  |  |  |  | __END__ |