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   73576 use 5.008_001;
  17         102  
11              
12 17     17   5708 use IO::Handle;
  17         58  
  17         845  
13 17     17   6917 use Socket 1.3;
  17         56382  
  17         6095  
14 17     17   134 use Carp;
  17         26  
  17         675  
15 17     17   81 use strict;
  17         28  
  17         301  
16 17     17   69 use Exporter;
  17         27  
  17         448  
17 17     17   5221 use Errno;
  17         18497  
  17         15692  
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   197 my $pkg = shift;
34 54 50 66     199 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         96 my $callpkg = caller;
38 54         43104 Exporter::export 'Socket', $callpkg, @_;
39             }
40             }
41              
42             sub new {
43 62     62 1 1001459 my($class,%arg) = @_;
44 62         971 my $sock = $class->SUPER::new();
45              
46 62         952 $sock->autoflush(1);
47              
48 62         765 ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout};
  62         517  
49              
50 62 100       726 return scalar(%arg) ? $sock->configure(\%arg)
51             : $sock;
52             }
53              
54             my @domain2pkg;
55              
56             sub register_domain {
57 34     34 0 101 my($p,$d) = @_;
58 34         95 $domain2pkg[$d] = $p;
59             }
60              
61             sub configure {
62 4     4 0 48 my($sock,$arg) = @_;
63 4         25 my $domain = delete $arg->{Domain};
64              
65 4 50       29 croak 'IO::Socket: Cannot configure a generic socket'
66             unless defined $domain;
67              
68 4 50       27 croak "IO::Socket: Unsupported socket domain"
69             unless defined $domain2pkg[$domain];
70              
71 4 50       37 croak "IO::Socket: Cannot configure socket in domain '$domain'"
72             unless ref($sock) eq "IO::Socket";
73              
74 4         30 bless($sock, $domain2pkg[$domain]);
75 4         82 $sock->configure($arg);
76             }
77              
78             sub socket {
79 43 50   43 1 149 @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
80 43         138 my($sock,$domain,$type,$protocol) = @_;
81              
82 43 50       2129 socket($sock,$domain,$type,$protocol) or
83             return undef;
84              
85 43         123 ${*$sock}{'io_socket_domain'} = $domain;
  43         334  
86 43         127 ${*$sock}{'io_socket_type'} = $type;
  43         176  
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       114 ${*$sock}{'io_socket_proto'} = $protocol if $protocol;
  36         181  
93              
94 43         510 $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 82 @_ == 2 or croak 'usage: $sock->connect(NAME)';
114 13         66 my $sock = shift;
115 13         62 my $addr = shift;
116 13         39 my $timeout = ${*$sock}{'io_socket_timeout'};
  13         66  
117 13         48 my $err;
118             my $blocking;
119              
120 13 100       80 $blocking = $sock->blocking(0) if $timeout;
121 13 100       1558 if (!connect($sock, $addr)) {
122 1 50 33     50 if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) {
    0 33        
      0        
      0        
123 1         1096 require IO::Select;
124              
125 1         7 my $sel = IO::Select->new( $sock );
126              
127 1         13 undef $!;
128 1         14 my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout);
129 1 50 33     34 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       70 $sock->blocking(1) if $blocking;
162              
163 13 50       38 $! = $err if $err;
164              
165 13 50       139 $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 254 my $sock = shift;
176              
177 10 50 33     310 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 2627667 @_ == 1 or croak 'usage: $sock->close()';
213 19         60 my $sock = shift;
214 19         39 ${*$sock}{'io_socket_peername'} = undef;
  19         156  
215 19         325 $sock->SUPER::close();
216             }
217              
218             sub bind {
219 28 50   28 1 93 @_ == 2 or croak 'usage: $sock->bind(NAME)';
220 28         51 my $sock = shift;
221 28         53 my $addr = shift;
222              
223 28 50       762 return bind($sock, $addr) ? $sock
224             : undef;
225             }
226              
227             sub listen {
228 20 50 33 20 1 212 @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])';
229 20         78 my($sock,$queue) = @_;
230 20 50 33     131 $queue = 5
231             unless $queue && $queue > 0;
232              
233 20 50       336 return listen($sock, $queue) ? $sock
234             : undef;
235             }
236              
237             sub accept {
238 21 50 33 21 1 3022922 @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])';
239 21         344 my $sock = shift;
240 21   33     395 my $pkg = shift || $sock;
241 21         118 my $timeout = ${*$sock}{'io_socket_timeout'};
  21         432  
242 21         408 my $new = $pkg->new(Timeout => $timeout);
243 21         130 my $peer = undef;
244              
245 21 100       133 if(defined $timeout) {
246 18         6481 require IO::Select;
247              
248 18         216 my $sel = IO::Select->new( $sock );
249              
250 18 100       89 unless ($sel->can_read($timeout)) {
251 1         57 $errstr = $@ = 'accept: timeout';
252 1 50       78 $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
253 1         35 return;
254             }
255             }
256              
257 20 50       2001535 $peer = accept($new,$sock)
258             or return;
259              
260 20         155 ${*$new}{$_} = ${*$sock}{$_} for qw( io_socket_domain io_socket_type io_socket_proto );
  60         337  
  60         320  
261              
262 20 50       136 return wantarray ? ($new, $peer)
263             : $new;
264             }
265              
266             sub sockname {
267 25 50   25 1 260 @_ == 1 or croak 'usage: $sock->sockname()';
268 25         321 getsockname($_[0]);
269             }
270              
271             sub peername {
272 2 50   2 1 6 @_ == 1 or croak 'usage: $sock->peername()';
273 2         3 my($sock) = @_;
274 2   33     2 ${*$sock}{'io_socket_peername'} ||= getpeername($sock);
  2         21  
275             }
276              
277             sub connected {
278 2 50   2 1 60 @_ == 1 or croak 'usage: $sock->connected()';
279 2         3 my($sock) = @_;
280 2         56 getpeername($sock);
281             }
282              
283             sub send {
284 6 50 33 6 1 1000296 @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])';
285 6         13 my $sock = $_[0];
286 6   50     30 my $flags = $_[2] || 0;
287 6         7 my $peer;
288              
289 6 100       79 if ($_[3]) {
    100          
290             # the caller explicitly requested a TO, so use it
291             # this is non-portable for "connected" UDP sockets
292 2         4 $peer = $_[3];
293             }
294             elsif (!defined getpeername($sock)) {
295             # we're not connected, so we require a peer from somewhere
296 1         3 $peer = $sock->peername;
297              
298 1 50       3 croak 'send: Cannot determine peer address'
299             unless(defined $peer);
300             }
301              
302 6 100       205 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     46 ${*$sock}{'io_socket_peername'} = $peer
  2         15  
308             if(@_ == 4 && defined $r);
309              
310 6         25 $r;
311             }
312              
313             sub recv {
314 6 50 33 6 1 2469 @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])';
315 6         24 my $sock = $_[0];
316 6         23 my $len = $_[2];
317 6   50     51 my $flags = $_[3] || 0;
318              
319             # remember who we recv'd from
320 6         3706 ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);
  6         78  
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 74 @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)';
339 13         129 my $r = getsockopt($_[0],$_[1],$_[2]);
340             # Just a guess
341 13 50 33     102 $r = unpack("i", $r)
342             if(defined $r && length($r) == $intsize);
343 13         34 $r;
344             }
345              
346             sub sockopt {
347 13     13 1 1447 my $sock = shift;
348 13 50       66 @_ == 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 2306 @_ == 1 or croak 'usage: $sock->sockdomain()';
371 10         30 my $sock = shift;
372 10 100       14 if (!defined(${*$sock}{'io_socket_domain'})) {
  10         57  
373 2         24 my $addr = $sock->sockname();
374 2 50       23 ${*$sock}{'io_socket_domain'} = sockaddr_family($addr)
  2         10  
375             if (defined($addr));
376             }
377 10         20 ${*$sock}{'io_socket_domain'};
  10         51  
378             }
379              
380             sub socktype {
381 10 50   10 1 1984 @_ == 1 or croak 'usage: $sock->socktype()';
382 10         20 my $sock = shift;
383 2         11 ${*$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         59  
  2         12  
385 10         35 ${*$sock}{'io_socket_type'}
  10         39  
386             }
387              
388             sub protocol {
389 10 50   10 1 1572 @_ == 1 or croak 'usage: $sock->protocol()';
390 10         20 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         66  
  5         26  
393 10         19 ${*$sock}{'io_socket_proto'};
  10         44  
394             }
395              
396             1;
397              
398             __END__