File Coverage

inc/IO/Socket.pm
Criterion Covered Total %
statement 68 182 37.3
branch 16 112 14.2
condition 7 58 12.0
subroutine 14 32 43.7
pod 13 25 52.0
total 118 409 28.8


line stmt bran cond sub pod time code
1             #line 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             require 5.006;
11 7     7   226558  
  7         84268  
  7         498  
12 7     7   10769 use IO::Handle;
  7         46700  
  7         7223  
13 7     7   80 use Socket 1.3;
  7         14  
  7         409  
14 7     7   37 use Carp;
  7         11  
  7         481  
15             use strict;
16 7     7   38 our(@ISA, $VERSION, @EXPORT_OK);
  7         12  
  7         241  
17 7     7   28640 use Exporter;
  7         14727  
  7         28845  
18             use Errno;
19              
20             # legacy
21              
22             require IO::Socket::INET;
23             require IO::Socket::UNIX if ($^O ne 'epoc' && $^O ne 'symbian');
24              
25             @ISA = qw(IO::Handle);
26              
27             $VERSION = "1.30_01";
28              
29             @EXPORT_OK = qw(sockatmark);
30              
31 23     23   1146 sub import {
32 23 50 66     153 my $pkg = shift;
33 0         0 if (@_ && $_[0] eq 'sockatmark') { # not very extensible but for now, fast
34             Exporter::export_to_level('IO::Socket', 1, $pkg, 'sockatmark');
35 23         65 } else {
36 23         22298 my $callpkg = caller;
37             Exporter::export 'Socket', $callpkg, @_;
38             }
39             }
40              
41 1     1 1 1001870 sub new {
42 1         86 my($class,%arg) = @_;
43             my $sock = $class->SUPER::new();
44 1         142  
45             $sock->autoflush(1);
46 1         178  
  1         11  
47             ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout};
48 1 50       51  
49             return scalar(%arg) ? $sock->configure(\%arg)
50             : $sock;
51             }
52              
53             my @domain2pkg;
54              
55 14     14 0 39774 sub register_domain {
56 14         58 my($p,$d) = @_;
57             $domain2pkg[$d] = $p;
58             }
59              
60 0     0 0 0 sub configure {
61 0         0 my($sock,$arg) = @_;
62             my $domain = delete $arg->{Domain};
63 0 0       0  
64             croak 'IO::Socket: Cannot configure a generic socket'
65             unless defined $domain;
66 0 0       0  
67             croak "IO::Socket: Unsupported socket domain"
68             unless defined $domain2pkg[$domain];
69 0 0       0  
70             croak "IO::Socket: Cannot configure socket in domain '$domain'"
71             unless ref($sock) eq "IO::Socket";
72 0         0  
73 0         0 bless($sock, $domain2pkg[$domain]);
74             $sock->configure($arg);
75             }
76              
77 1 50   1 0 1138 sub socket {
78 1         4 @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
79             my($sock,$domain,$type,$protocol) = @_;
80 1 50       54  
81             socket($sock,$domain,$type,$protocol) or
82             return undef;
83 1         3  
  1         14  
84 1         5 ${*$sock}{'io_socket_domain'} = $domain;
  1         12  
85 1         5 ${*$sock}{'io_socket_type'} = $type;
  1         8  
86             ${*$sock}{'io_socket_proto'} = $protocol;
87 1         4  
88             $sock;
89             }
90              
91 0 0   0 1 0 sub socketpair {
92 0         0 @_ == 4 || croak 'usage: IO::Socket->socketpair(DOMAIN, TYPE, PROTOCOL)';
93 0         0 my($class,$domain,$type,$protocol) = @_;
94 0         0 my $sock1 = $class->new();
95             my $sock2 = $class->new();
96 0 0       0  
97             socketpair($sock1,$sock2,$domain,$type,$protocol) or
98             return ();
99 0         0  
  0         0  
  0         0  
100 0         0 ${*$sock1}{'io_socket_type'} = ${*$sock2}{'io_socket_type'} = $type;
  0         0  
  0         0  
101             ${*$sock1}{'io_socket_proto'} = ${*$sock2}{'io_socket_proto'} = $protocol;
102 0         0  
103             ($sock1,$sock2);
104             }
105              
106 1 50   1 0 58 sub connect {
107 1         3 @_ == 2 or croak 'usage: $sock->connect(NAME)';
108 1         9 my $sock = shift;
109 1         8 my $addr = shift;
  1         4  
110 1         2 my $timeout = ${*$sock}{'io_socket_timeout'};
111             my $err;
112             my $blocking;
113 1 50       11  
114 1 50       2558 $blocking = $sock->blocking(0) if $timeout;
115 0 0 0     0 if (!connect($sock, $addr)) {
    0 0        
      0        
      0        
116 0         0 if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) {
117             require IO::Select;
118 0         0  
119             my $sel = new IO::Select $sock;
120 0         0  
121 0 0 0     0 undef $!;
    0          
122 0   0     0 if (!$sel->can_write($timeout)) {
123 0         0 $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
124             $@ = "connect: timeout";
125             }
126             elsif (!connect($sock,$addr) &&
127             not ($!{EISCONN} || ($! == 10022 && $^O eq 'MSWin32'))
128             ) {
129             # Some systems refuse to re-connect() to
130             # an already open socket and set errno to EISCONN.
131 0         0 # Windows sets errno to WSAEINVAL (10022)
132 0         0 $err = $!;
133             $@ = "connect: $!";
134             }
135             }
136 0         0 elsif ($blocking || !($!{EINPROGRESS} || $!{EWOULDBLOCK})) {
137 0         0 $err = $!;
138             $@ = "connect: $!";
139             }
140             }
141 1 50       11  
142             $sock->blocking(1) if $blocking;
143 1 50       8  
144             $! = $err if $err;
145 1 50       17  
146             $err ? undef : $sock;
147             }
148              
149             # Enable/disable blocking IO on sockets.
150             # Without args return the current status of blocking,
151             # with args change the mode as appropriate, returning the
152             # old setting, or in case of error during the mode change
153             # undef.
154              
155 0     0 1 0 sub blocking {
156             my $sock = shift;
157 0 0       0  
158             return $sock->SUPER::blocking(@_)
159             if $^O ne 'MSWin32';
160              
161             # Windows handles blocking differently
162             #
163             # http://groups.google.co.uk/group/perl.perl5.porters/browse_thread/thread/b4e2b1d88280ddff/630b667a66e3509f?#630b667a66e3509f
164             # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ioctlsocket_2.asp
165             #
166             # 0x8004667e is FIONBIO
167             #
168             # which is used to set blocking behaviour.
169              
170             # NOTE:
171             # This is a little confusing, the perl keyword for this is
172             # 'blocking' but the OS level behaviour is 'non-blocking', probably
173             # because sockets are blocking by default.
174             # Therefore internally we have to reverse the semantics.
175 0         0  
  0         0  
176             my $orig= !${*$sock}{io_sock_nonblocking};
177 0 0       0
178             return $orig unless @_;
179 0         0  
180             my $block = shift;
181 0 0       0
182 0 0       0 if ( !$block != !$orig ) {
  0         0  
183 0 0       0 ${*$sock}{io_sock_nonblocking} = $block ? 0 : 1;
  0         0  
184             ioctl($sock, 0x8004667e, pack("L!",${*$sock}{io_sock_nonblocking}))
185             or return undef;
186             }
187 0         0
188             return $orig;
189             }
190              
191              
192 1 50   1 0 29 sub close {
193 1         2 @_ == 1 or croak 'usage: $sock->close()';
194 1         3 my $sock = shift;
  1         6  
195 1         24 ${*$sock}{'io_socket_peername'} = undef;
196             $sock->SUPER::close();
197             }
198              
199 0 0   0 0 0 sub bind {
200 0         0 @_ == 2 or croak 'usage: $sock->bind(NAME)';
201 0         0 my $sock = shift;
202             my $addr = shift;
203 0 0       0  
204             return bind($sock, $addr) ? $sock
205             : undef;
206             }
207              
208 0 0 0 0 0 0 sub listen {
209 0         0 @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])';
210 0 0 0     0 my($sock,$queue) = @_;
211             $queue = 5
212             unless $queue && $queue > 0;
213 0 0       0  
214             return listen($sock, $queue) ? $sock
215             : undef;
216             }
217              
218 0 0 0 0 1 0 sub accept {
219 0         0 @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])';
220 0   0     0 my $sock = shift;
221 0         0 my $pkg = shift || $sock;
  0         0  
222 0         0 my $timeout = ${*$sock}{'io_socket_timeout'};
223 0         0 my $new = $pkg->new(Timeout => $timeout);
224             my $peer = undef;
225 0 0       0  
226 0         0 if(defined $timeout) {
227             require IO::Select;
228 0         0  
229             my $sel = new IO::Select $sock;
230 0 0       0  
231 0         0 unless ($sel->can_read($timeout)) {
232 0 0       0 $@ = 'accept: timeout';
233 0         0 $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
234             return;
235             }
236             }
237 0 0       0  
238             $peer = accept($new,$sock)
239             or return;
240 0 0       0  
241             return wantarray ? ($new, $peer)
242             : $new;
243             }
244              
245 0 0   0 0 0 sub sockname {
246 0         0 @_ == 1 or croak 'usage: $sock->sockname()';
247             getsockname($_[0]);
248             }
249              
250 1 50   1 0 10 sub peername {
251 1         2 @_ == 1 or croak 'usage: $sock->peername()';
252 1   33     5 my($sock) = @_;
  1         50  
253             ${*$sock}{'io_socket_peername'} ||= getpeername($sock);
254             }
255              
256 0 0   0 1 0 sub connected {
257 0         0 @_ == 1 or croak 'usage: $sock->connected()';
258 0         0 my($sock) = @_;
259             getpeername($sock);
260             }
261              
262 1 50 33 1 0 74 sub send {
263 1         3 @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])';
264 1   50     11 my $sock = $_[0];
265 1   33     32 my $flags = $_[2] || 0;
266             my $peer = $_[3] || $sock->peername;
267 1 50       6  
268             croak 'send: Cannot determine peer address'
269             unless(defined $peer);
270 1 50       120  
271             my $r = defined(getpeername($sock))
272             ? send($sock, $_[1], $flags)
273             : send($sock, $_[1], $flags, $peer);
274              
275 1 50 33     30 # remember who we send to, if it was successful
  0         0  
276             ${*$sock}{'io_socket_peername'} = $peer
277             if(@_ == 4 && defined $r);
278 1         6  
279             $r;
280             }
281              
282 0 0 0 0 0   sub recv {
283 0           @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])';
284 0           my $sock = $_[0];
285 0   0       my $len = $_[2];
286             my $flags = $_[3] || 0;
287              
288 0           # remember who we recv'd from
  0            
289             ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);
290             }
291              
292 0 0   0 0   sub shutdown {
293 0           @_ == 2 or croak 'usage: $sock->shutdown(HOW)';
294 0           my($sock, $how) = @_;
  0            
295 0           ${*$sock}{'io_socket_peername'} = undef;
296             shutdown($sock, $how);
297             }
298              
299 0 0   0 1   sub setsockopt {
300 0           @_ == 4 or croak '$sock->setsockopt(LEVEL, OPTNAME, OPTVAL)';
301             setsockopt($_[0],$_[1],$_[2],$_[3]);
302             }
303              
304             my $intsize = length(pack("i",0));
305              
306 0 0   0 1   sub getsockopt {
307 0           @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)';
308             my $r = getsockopt($_[0],$_[1],$_[2]);
309 0 0 0       # Just a guess
310             $r = unpack("i", $r)
311 0           if(defined $r && length($r) == $intsize);
312             $r;
313             }
314              
315 0     0 1   sub sockopt {
316 0 0         my $sock = shift;
317             @_ == 1 ? $sock->getsockopt(SOL_SOCKET,@_)
318             : $sock->setsockopt(SOL_SOCKET,@_);
319             }
320              
321 0 0   0 1   sub atmark {
322 0           @_ == 1 or croak 'usage: $sock->atmark()';
323 0           my($sock) = @_;
324             sockatmark($sock);
325             }
326              
327 0 0 0 0 1   sub timeout {
328 0           @_ == 1 || @_ == 2 or croak 'usage: $sock->timeout([VALUE])';
329 0           my($sock,$val) = @_;
  0            
330             my $r = ${*$sock}{'io_socket_timeout'};
331 0 0          
  0 0          
332             ${*$sock}{'io_socket_timeout'} = defined $val ? 0 + $val : $val
333             if(@_ == 2);
334 0            
335             $r;
336             }
337              
338 0 0   0 1   sub sockdomain {
339 0           @_ == 1 or croak 'usage: $sock->sockdomain()';
340 0           my $sock = shift;
  0            
341             ${*$sock}{'io_socket_domain'};
342             }
343              
344 0 0   0 1   sub socktype {
345 0           @_ == 1 or croak 'usage: $sock->socktype()';
346 0           my $sock = shift;
  0            
347             ${*$sock}{'io_socket_type'}
348             }
349              
350 0 0   0 1   sub protocol {
351 0           @_ == 1 or croak 'usage: $sock->protocol()';
352 0           my($sock) = @_;
  0            
353             ${*$sock}{'io_socket_proto'};
354             }
355              
356             1;
357              
358             __END__