File Coverage

blib/lib/IO/Socket.pm
Criterion Covered Total %
statement 160 206 77.6
branch 69 128 53.9
condition 25 64 39.0
subroutine 28 33 84.8
pod 21 25 84.0
total 303 456 66.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 18     18   335705 use 5.008_001;
  18         69  
11              
12 18     18   8945 use IO::Handle;
  18         53  
  18         2474  
13 18     18   10854 use Socket 1.3;
  18         121099  
  18         12243  
14 18     18   183 use Carp;
  18         36  
  18         1232  
15 18     18   121 use strict;
  18         29  
  18         539  
16 18     18   85 use Exporter;
  18         33  
  18         677  
17 18     18   6497 use Errno;
  18         21009  
  18         24069  
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.55";
27              
28             our @EXPORT_OK = qw(sockatmark);
29              
30             our $errstr;
31              
32             sub import {
33 57     57   253 my $pkg = shift;
34 57 50 66     266 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 57         148 my $callpkg = caller;
38 57         836736 Exporter::export 'Socket', $callpkg, @_;
39             }
40             }
41              
42             sub new {
43 63     63 1 1004335 my($class,%arg) = @_;
44 63         1713 my $sock = $class->SUPER::new();
45              
46 63         1486 $sock->autoflush(1);
47              
48 63         1216 ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout};
  63         1355  
49              
50 63 100       1745 return scalar(%arg) ? $sock->configure(\%arg)
51             : $sock;
52             }
53              
54             my @domain2pkg;
55              
56             sub register_domain {
57 36     36 0 118 my($p,$d) = @_;
58 36         153 $domain2pkg[$d] = $p;
59             }
60              
61             sub configure {
62 4     4 0 56 my($sock,$arg) = @_;
63 4         23 my $domain = delete $arg->{Domain};
64              
65 4 50       38 croak 'IO::Socket: Cannot configure a generic socket'
66             unless defined $domain;
67              
68 4 50       53 croak "IO::Socket: Unsupported socket domain"
69             unless defined $domain2pkg[$domain];
70              
71 4 50       36 croak "IO::Socket: Cannot configure socket in domain '$domain'"
72             unless ref($sock) eq "IO::Socket";
73              
74 4         36 bless($sock, $domain2pkg[$domain]);
75 4         56 $sock->configure($arg);
76             }
77              
78             sub socket {
79 44 50   44 1 211 @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
80 44         172 my($sock,$domain,$type,$protocol) = @_;
81              
82 44 50       2510 socket($sock,$domain,$type,$protocol) or
83             return undef;
84              
85 44         137 ${*$sock}{'io_socket_domain'} = $domain;
  44         533  
86 44         113 ${*$sock}{'io_socket_type'} = $type;
  44         172  
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 44 100       247 ${*$sock}{'io_socket_proto'} = $protocol if $protocol;
  37         241  
93              
94 44         239 $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 14 50   14 0 169 @_ == 2 or croak 'usage: $sock->connect(NAME)';
114 14         192 my $sock = shift;
115 14         81 my $addr = shift;
116 14         1181 my $timeout = ${*$sock}{'io_socket_timeout'};
  14         77  
117 14         86 my $err;
118             my $blocking;
119              
120 14 100       169 $blocking = $sock->blocking(0) if $timeout;
121 14 100       4900 if (!connect($sock, $addr)) {
122 2 100 33     76 if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) {
    50 66        
      33        
      33        
123 1         4547 require IO::Select;
124              
125 1         7 my $sel = IO::Select->new( $sock );
126              
127 1         2 undef $!;
128 1         3 my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout);
129 1 50 33     39 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 1         26 $err = $!;
157 1         4 $errstr = $@ = "connect: $!";
158             }
159             }
160              
161 14 100       188 $sock->blocking(1) if $blocking;
162              
163 14 100       55 $! = $err if $err;
164              
165 14 100       147 $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 260 my $sock = shift;
176              
177 10 50 33     690 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 20 50   20 0 2986033 @_ == 1 or croak 'usage: $sock->close()';
213 20         207 my $sock = shift;
214 20         107 ${*$sock}{'io_socket_peername'} = undef;
  20         237  
215 20         477 $sock->SUPER::close();
216             }
217              
218             sub bind {
219 28 50   28 1 105 @_ == 2 or croak 'usage: $sock->bind(NAME)';
220 28         52 my $sock = shift;
221 28         44 my $addr = shift;
222              
223 28 50       1688 return bind($sock, $addr) ? $sock
224             : undef;
225             }
226              
227             sub listen {
228 20 50 33 20 1 192 @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])';
229 20         70 my($sock,$queue) = @_;
230 20 50 33     191 $queue = 5
231             unless $queue && $queue > 0;
232              
233 20 50       329 return listen($sock, $queue) ? $sock
234             : undef;
235             }
236              
237             sub accept {
238 21 50 33 21 1 3050352 @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])';
239 21         418 my $sock = shift;
240 21   33     538 my $pkg = shift || $sock;
241 21         152 my $timeout = ${*$sock}{'io_socket_timeout'};
  21         1139  
242 21         967 my $new = $pkg->new(Timeout => $timeout);
243 21         198 my $peer = undef;
244              
245 21 100       363 if(defined $timeout) {
246 18         15173 require IO::Select;
247              
248 18         469 my $sel = IO::Select->new( $sock );
249              
250 18 100       77 unless ($sel->can_read($timeout)) {
251 1         64 $errstr = $@ = 'accept: timeout';
252 1 50       45 $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
253 1         174 return;
254             }
255             }
256              
257 20 50       2005366 $peer = accept($new,$sock)
258             or return;
259              
260 20         193 ${*$new}{$_} = ${*$sock}{$_} for qw( io_socket_domain io_socket_type io_socket_proto );
  60         345  
  60         292  
261              
262 20 50       171 return wantarray ? ($new, $peer)
263             : $new;
264             }
265              
266             sub sockname {
267 25 50   25 1 251 @_ == 1 or croak 'usage: $sock->sockname()';
268 25         296 getsockname($_[0]);
269             }
270              
271             sub peername {
272 2 50   2 1 4 @_ == 1 or croak 'usage: $sock->peername()';
273 2         23 my($sock) = @_;
274 2   33     2 ${*$sock}{'io_socket_peername'} ||= getpeername($sock);
  2         7  
275             }
276              
277             sub connected {
278 2 50   2 1 70 @_ == 1 or croak 'usage: $sock->connected()';
279 2         5 my($sock) = @_;
280 2         18 getpeername($sock);
281             }
282              
283             sub send {
284 6 50 33 6 1 1002795 @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])';
285 6         10 my $sock = $_[0];
286 6   50     19 my $flags = $_[2] || 0;
287 6         8 my $peer;
288              
289 6 100       101 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         1 $peer = $sock->peername;
297              
298 1 50       4 croak 'send: Cannot determine peer address'
299             unless(defined $peer);
300             }
301              
302 6 100       203 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     41 ${*$sock}{'io_socket_peername'} = $peer
  2         15  
308             if(@_ == 4 && defined $r);
309              
310 6         16 $r;
311             }
312              
313             sub recv {
314 6 50 33 6 1 7297 @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])';
315 6         61 my $sock = $_[0];
316 6         45 my $len = $_[2];
317 6   50     117 my $flags = $_[3] || 0;
318              
319             # remember who we recv'd from
320 6         9384 ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);
  6         112  
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 30 @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)';
339 13         145 my $r = getsockopt($_[0],$_[1],$_[2]);
340             # Just a guess
341 13 50 33     142 $r = unpack("i", $r)
342             if(defined $r && length($r) == $intsize);
343 13         34 $r;
344             }
345              
346             sub sockopt {
347 13     13 1 2734 my $sock = shift;
348 13 50       108 @_ == 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 3428 @_ == 1 or croak 'usage: $sock->sockdomain()';
371 10         22 my $sock = shift;
372 10 100       15 if (!defined(${*$sock}{'io_socket_domain'})) {
  10         50  
373 2         18 my $addr = $sock->sockname();
374 2 50       10 ${*$sock}{'io_socket_domain'} = sockaddr_family($addr)
  2         11  
375             if (defined($addr));
376             }
377 10         19 ${*$sock}{'io_socket_domain'};
  10         72  
378             }
379              
380             sub socktype {
381 10 50   10 1 5538 @_ == 1 or croak 'usage: $sock->socktype()';
382 10         16 my $sock = shift;
383 2         6 ${*$sock}{'io_socket_type'} = $sock->sockopt(Socket::SO_TYPE)
384 10 100 66     14 if (!defined(${*$sock}{'io_socket_type'}) && defined(eval{Socket::SO_TYPE}));
  10         56  
  2         9  
385 10         14 ${*$sock}{'io_socket_type'}
  10         73  
386             }
387              
388             sub protocol {
389 10 50   10 1 2933 @_ == 1 or croak 'usage: $sock->protocol()';
390 10         22 my($sock) = @_;
391 5         19 ${*$sock}{'io_socket_proto'} = $sock->sockopt(Socket::SO_PROTOCOL)
392 10 100 66     15 if (!defined(${*$sock}{'io_socket_proto'}) && defined(eval{Socket::SO_PROTOCOL}));
  10         77  
  5         39  
393 10         16 ${*$sock}{'io_socket_proto'};
  10         60  
394             }
395              
396             1;
397              
398             __END__