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   72650 use 5.008_001;
  17         92  
11              
12 17     17   5879 use IO::Handle;
  17         57  
  17         751  
13 17     17   6888 use Socket 1.3;
  17         56182  
  17         5995  
14 17     17   110 use Carp;
  17         26  
  17         639  
15 17     17   77 use strict;
  17         21  
  17         280  
16 17     17   72 use Exporter;
  17         22  
  17         441  
17 17     17   4945 use Errno;
  17         17451  
  17         15824  
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.51";
27              
28             our @EXPORT_OK = qw(sockatmark);
29              
30             our $errstr;
31              
32             sub import {
33 54     54   185 my $pkg = shift;
34 54 50 66     181 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         100 my $callpkg = caller;
38 54         40849 Exporter::export 'Socket', $callpkg, @_;
39             }
40             }
41              
42             sub new {
43 62     62 1 1001206 my($class,%arg) = @_;
44 62         1158 my $sock = $class->SUPER::new();
45              
46 62         1033 $sock->autoflush(1);
47              
48 62         765 ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout};
  62         428  
49              
50 62 100       657 return scalar(%arg) ? $sock->configure(\%arg)
51             : $sock;
52             }
53              
54             my @domain2pkg;
55              
56             sub register_domain {
57 34     34 0 80 my($p,$d) = @_;
58 34         97 $domain2pkg[$d] = $p;
59             }
60              
61             sub configure {
62 4     4 0 37 my($sock,$arg) = @_;
63 4         34 my $domain = delete $arg->{Domain};
64              
65 4 50       39 croak 'IO::Socket: Cannot configure a generic socket'
66             unless defined $domain;
67              
68 4 50       32 croak "IO::Socket: Unsupported socket domain"
69             unless defined $domain2pkg[$domain];
70              
71 4 50       25 croak "IO::Socket: Cannot configure socket in domain '$domain'"
72             unless ref($sock) eq "IO::Socket";
73              
74 4         21 bless($sock, $domain2pkg[$domain]);
75 4         50 $sock->configure($arg);
76             }
77              
78             sub socket {
79 43 50   43 1 136 @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
80 43         137 my($sock,$domain,$type,$protocol) = @_;
81              
82 43 50       1903 socket($sock,$domain,$type,$protocol) or
83             return undef;
84              
85 43         120 ${*$sock}{'io_socket_domain'} = $domain;
  43         306  
86 43         125 ${*$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       163 ${*$sock}{'io_socket_proto'} = $protocol if $protocol;
  36         182  
93              
94 43         216 $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 76 @_ == 2 or croak 'usage: $sock->connect(NAME)';
114 13         37 my $sock = shift;
115 13         59 my $addr = shift;
116 13         33 my $timeout = ${*$sock}{'io_socket_timeout'};
  13         53  
117 13         36 my $err;
118             my $blocking;
119              
120 13 100       75 $blocking = $sock->blocking(0) if $timeout;
121 13 100       1285 if (!connect($sock, $addr)) {
122 1 50 33     47 if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) {
    0 33        
      0        
      0        
123 1         1889 require IO::Select;
124              
125 1         7 my $sel = IO::Select->new( $sock );
126              
127 1         3 undef $!;
128 1         4 my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout);
129 1 50 33     27 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       73 $sock->blocking(1) if $blocking;
162              
163 13 50       53 $! = $err if $err;
164              
165 13 50       113 $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 211 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 2851435 @_ == 1 or croak 'usage: $sock->close()';
213 19         47 my $sock = shift;
214 19         41 ${*$sock}{'io_socket_peername'} = undef;
  19         159  
215 19         263 $sock->SUPER::close();
216             }
217              
218             sub bind {
219 28 50   28 1 80 @_ == 2 or croak 'usage: $sock->bind(NAME)';
220 28         63 my $sock = shift;
221 28         54 my $addr = shift;
222              
223 28 50       703 return bind($sock, $addr) ? $sock
224             : undef;
225             }
226              
227             sub listen {
228 20 50 33 20 1 1033 @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])';
229 20         83 my($sock,$queue) = @_;
230 20 50 33     177 $queue = 5
231             unless $queue && $queue > 0;
232              
233 20 50       318 return listen($sock, $queue) ? $sock
234             : undef;
235             }
236              
237             sub accept {
238 21 50 33 21 1 3019005 @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])';
239 21         338 my $sock = shift;
240 21   33     641 my $pkg = shift || $sock;
241 21         67 my $timeout = ${*$sock}{'io_socket_timeout'};
  21         595  
242 21         396 my $new = $pkg->new(Timeout => $timeout);
243 21         55 my $peer = undef;
244              
245 21 100       134 if(defined $timeout) {
246 18         7030 require IO::Select;
247              
248 18         199 my $sel = IO::Select->new( $sock );
249              
250 18 100       82 unless ($sel->can_read($timeout)) {
251 1         25 $errstr = $@ = 'accept: timeout';
252 1 50       46 $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
253 1         18 return;
254             }
255             }
256              
257 20 50       2001791 $peer = accept($new,$sock)
258             or return;
259              
260 20         112 ${*$new}{$_} = ${*$sock}{$_} for qw( io_socket_domain io_socket_type io_socket_proto );
  60         339  
  60         237  
261              
262 20 50       148 return wantarray ? ($new, $peer)
263             : $new;
264             }
265              
266             sub sockname {
267 25 50   25 1 261 @_ == 1 or croak 'usage: $sock->sockname()';
268 25         322 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     3 ${*$sock}{'io_socket_peername'} ||= getpeername($sock);
  2         23  
275             }
276              
277             sub connected {
278 2 50   2 1 47 @_ == 1 or croak 'usage: $sock->connected()';
279 2         3 my($sock) = @_;
280 2         42 getpeername($sock);
281             }
282              
283             sub send {
284 6 50 33 6 1 1000552 @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])';
285 6         15 my $sock = $_[0];
286 6   50     34 my $flags = $_[2] || 0;
287 6         9 my $peer;
288              
289 6 100       149 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         9 $peer = $sock->peername;
297              
298 1 50       2 croak 'send: Cannot determine peer address'
299             unless(defined $peer);
300             }
301              
302 6 100       222 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     39 ${*$sock}{'io_socket_peername'} = $peer
  2         13  
308             if(@_ == 4 && defined $r);
309              
310 6         31 $r;
311             }
312              
313             sub recv {
314 6 50 33 6 1 2233 @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])';
315 6         32 my $sock = $_[0];
316 6         11 my $len = $_[2];
317 6   50     77 my $flags = $_[3] || 0;
318              
319             # remember who we recv'd from
320 6         6357 ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);
  6         76  
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 29 @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)';
339 13         121 my $r = getsockopt($_[0],$_[1],$_[2]);
340             # Just a guess
341 13 50 33     98 $r = unpack("i", $r)
342             if(defined $r && length($r) == $intsize);
343 13         34 $r;
344             }
345              
346             sub sockopt {
347 13     13 1 1430 my $sock = shift;
348 13 50       79 @_ == 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 2109 @_ == 1 or croak 'usage: $sock->sockdomain()';
371 10         29 my $sock = shift;
372 10 100       12 if (!defined(${*$sock}{'io_socket_domain'})) {
  10         50  
373 2         24 my $addr = $sock->sockname();
374 2 50       16 ${*$sock}{'io_socket_domain'} = sockaddr_family($addr)
  2         11  
375             if (defined($addr));
376             }
377 10         21 ${*$sock}{'io_socket_domain'};
  10         47  
378             }
379              
380             sub socktype {
381 10 50   10 1 1828 @_ == 1 or croak 'usage: $sock->socktype()';
382 10         18 my $sock = shift;
383 2         7 ${*$sock}{'io_socket_type'} = $sock->sockopt(Socket::SO_TYPE)
384 10 100 66     212 if (!defined(${*$sock}{'io_socket_type'}) && defined(eval{Socket::SO_TYPE}));
  10         65  
  2         13  
385 10         45 ${*$sock}{'io_socket_type'}
  10         46  
386             }
387              
388             sub protocol {
389 10 50   10 1 1475 @_ == 1 or croak 'usage: $sock->protocol()';
390 10         25 my($sock) = @_;
391 5         14 ${*$sock}{'io_socket_proto'} = $sock->sockopt(Socket::SO_PROTOCOL)
392 10 100 66     18 if (!defined(${*$sock}{'io_socket_proto'}) && defined(eval{Socket::SO_PROTOCOL}));
  10         62  
  5         28  
393 10         20 ${*$sock}{'io_socket_proto'};
  10         59  
394             }
395              
396             1;
397              
398             __END__