File Coverage

blib/lib/IO/Socket.pm
Criterion Covered Total %
statement 158 206 76.7
branch 65 128 50.7
condition 22 64 34.3
subroutine 28 33 84.8
pod 21 25 84.0
total 294 456 64.4


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__