File Coverage

inc/IO/Socket.pm
Criterion Covered Total %
statement 24 169 14.2
branch 1 102 0.9
condition 1 52 1.9
subroutine 8 31 25.8
pod 12 24 50.0
total 46 378 12.1


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 5     5   2616  
  5         22222  
  5         191  
12 5     5   2337 use IO::Handle;
  5         12912  
  5         1690  
13 5     5   27 use Socket 1.3;
  5         97  
  5         225  
14 5     5   21 use Carp;
  5         3  
  5         169  
15             use strict;
16 5     5   15 our(@ISA, $VERSION, @EXPORT_OK);
  5         4  
  5         110  
17 5     5   1862 use Exporter;
  5         4342  
  5         6857  
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";
28              
29             @EXPORT_OK = qw(sockatmark);
30              
31 15     15   223 sub import {
32 15 50 33     45 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 15         23 } else {
36 15         5089 my $callpkg = caller;
37             Exporter::export 'Socket', $callpkg, @_;
38             }
39             }
40              
41 0     0 1 0 sub new {
42 0         0 my($class,%arg) = @_;
43             my $sock = $class->SUPER::new();
44 0         0  
45             $sock->autoflush(1);
46 0         0  
  0         0  
47             ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout};
48 0 0       0  
49             return scalar(%arg) ? $sock->configure(\%arg)
50             : $sock;
51             }
52              
53             my @domain2pkg;
54              
55 10     10 0 1808 sub register_domain {
56 10         20 my($p,$d) = @_;
57             $domain2pkg[$d] = $p;
58             }
59              
60 0     0 0   sub configure {
61 0           my($sock,$arg) = @_;
62             my $domain = delete $arg->{Domain};
63 0 0          
64             croak 'IO::Socket: Cannot configure a generic socket'
65             unless defined $domain;
66 0 0          
67             croak "IO::Socket: Unsupported socket domain"
68             unless defined $domain2pkg[$domain];
69 0 0          
70             croak "IO::Socket: Cannot configure socket in domain '$domain'"
71             unless ref($sock) eq "IO::Socket";
72 0            
73 0           bless($sock, $domain2pkg[$domain]);
74             $sock->configure($arg);
75             }
76              
77 0 0   0 0   sub socket {
78 0           @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)';
79             my($sock,$domain,$type,$protocol) = @_;
80 0 0          
81             socket($sock,$domain,$type,$protocol) or
82             return undef;
83 0            
  0            
84 0           ${*$sock}{'io_socket_domain'} = $domain;
  0            
85 0           ${*$sock}{'io_socket_type'} = $type;
  0            
86             ${*$sock}{'io_socket_proto'} = $protocol;
87 0            
88             $sock;
89             }
90              
91 0 0   0 1   sub socketpair {
92 0           @_ == 4 || croak 'usage: IO::Socket->socketpair(DOMAIN, TYPE, PROTOCOL)';
93 0           my($class,$domain,$type,$protocol) = @_;
94 0           my $sock1 = $class->new();
95             my $sock2 = $class->new();
96 0 0          
97             socketpair($sock1,$sock2,$domain,$type,$protocol) or
98             return ();
99 0            
  0            
  0            
100 0           ${*$sock1}{'io_socket_type'} = ${*$sock2}{'io_socket_type'} = $type;
  0            
  0            
101             ${*$sock1}{'io_socket_proto'} = ${*$sock2}{'io_socket_proto'} = $protocol;
102 0            
103             ($sock1,$sock2);
104             }
105              
106 0 0   0 0   sub connect {
107 0           @_ == 2 or croak 'usage: $sock->connect(NAME)';
108 0           my $sock = shift;
109 0           my $addr = shift;
  0            
110 0           my $timeout = ${*$sock}{'io_socket_timeout'};
111             my $err;
112             my $blocking;
113 0 0          
114 0 0         $blocking = $sock->blocking(0) if $timeout;
115 0 0 0       if (!connect($sock, $addr)) {
    0 0        
116 0           if (defined $timeout && $!{EINPROGRESS}) {
117             require IO::Select;
118 0            
119             my $sel = new IO::Select $sock;
120 0 0 0        
    0          
121 0   0       if (!$sel->can_write($timeout)) {
122 0           $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
123             $@ = "connect: timeout";
124             }
125             elsif (!connect($sock,$addr) && not $!{EISCONN}) {
126             # Some systems refuse to re-connect() to
127 0           # an already open socket and set errno to EISCONN.
128 0           $err = $!;
129             $@ = "connect: $!";
130             }
131             }
132 0           elsif ($blocking || !$!{EINPROGRESS}) {
133 0           $err = $!;
134             $@ = "connect: $!";
135             }
136             }
137 0 0          
138             $sock->blocking(1) if $blocking;
139 0 0          
140             $! = $err if $err;
141 0 0          
142             $err ? undef : $sock;
143             }
144              
145 0 0   0 0   sub close {
146 0           @_ == 1 or croak 'usage: $sock->close()';
147 0           my $sock = shift;
  0            
148 0           ${*$sock}{'io_socket_peername'} = undef;
149             $sock->SUPER::close();
150             }
151              
152 0 0   0 0   sub bind {
153 0           @_ == 2 or croak 'usage: $sock->bind(NAME)';
154 0           my $sock = shift;
155             my $addr = shift;
156 0 0          
157             return bind($sock, $addr) ? $sock
158             : undef;
159             }
160              
161 0 0 0 0 0   sub listen {
162 0           @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])';
163 0 0 0       my($sock,$queue) = @_;
164             $queue = 5
165             unless $queue && $queue > 0;
166 0 0          
167             return listen($sock, $queue) ? $sock
168             : undef;
169             }
170              
171 0 0 0 0 1   sub accept {
172 0           @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])';
173 0   0       my $sock = shift;
174 0           my $pkg = shift || $sock;
  0            
175 0           my $timeout = ${*$sock}{'io_socket_timeout'};
176 0           my $new = $pkg->new(Timeout => $timeout);
177             my $peer = undef;
178 0 0          
179 0           if(defined $timeout) {
180             require IO::Select;
181 0            
182             my $sel = new IO::Select $sock;
183 0 0          
184 0           unless ($sel->can_read($timeout)) {
185 0 0         $@ = 'accept: timeout';
186 0           $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1);
187             return;
188             }
189             }
190 0 0          
191             $peer = accept($new,$sock)
192             or return;
193 0 0          
194             return wantarray ? ($new, $peer)
195             : $new;
196             }
197              
198 0 0   0 0   sub sockname {
199 0           @_ == 1 or croak 'usage: $sock->sockname()';
200             getsockname($_[0]);
201             }
202              
203 0 0   0 0   sub peername {
204 0           @_ == 1 or croak 'usage: $sock->peername()';
205 0   0       my($sock) = @_;
  0            
206             ${*$sock}{'io_socket_peername'} ||= getpeername($sock);
207             }
208              
209 0 0   0 1   sub connected {
210 0           @_ == 1 or croak 'usage: $sock->connected()';
211 0           my($sock) = @_;
212             getpeername($sock);
213             }
214              
215 0 0 0 0 0   sub send {
216 0           @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])';
217 0   0       my $sock = $_[0];
218 0   0       my $flags = $_[2] || 0;
219             my $peer = $_[3] || $sock->peername;
220 0 0          
221             croak 'send: Cannot determine peer address'
222             unless($peer);
223 0 0          
224             my $r = defined(getpeername($sock))
225             ? send($sock, $_[1], $flags)
226             : send($sock, $_[1], $flags, $peer);
227              
228 0 0 0       # remember who we send to, if it was successful
  0            
229             ${*$sock}{'io_socket_peername'} = $peer
230             if(@_ == 4 && defined $r);
231 0            
232             $r;
233             }
234              
235 0 0 0 0 0   sub recv {
236 0           @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])';
237 0           my $sock = $_[0];
238 0   0       my $len = $_[2];
239             my $flags = $_[3] || 0;
240              
241 0           # remember who we recv'd from
  0            
242             ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);
243             }
244              
245 0 0   0 0   sub shutdown {
246 0           @_ == 2 or croak 'usage: $sock->shutdown(HOW)';
247 0           my($sock, $how) = @_;
  0            
248 0           ${*$sock}{'io_socket_peername'} = undef;
249             shutdown($sock, $how);
250             }
251              
252 0 0   0 1   sub setsockopt {
253 0           @_ == 4 or croak '$sock->setsockopt(LEVEL, OPTNAME, OPTVAL)';
254             setsockopt($_[0],$_[1],$_[2],$_[3]);
255             }
256              
257             my $intsize = length(pack("i",0));
258              
259 0 0   0 1   sub getsockopt {
260 0           @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)';
261             my $r = getsockopt($_[0],$_[1],$_[2]);
262 0 0 0       # Just a guess
263             $r = unpack("i", $r)
264 0           if(defined $r && length($r) == $intsize);
265             $r;
266             }
267              
268 0     0 1   sub sockopt {
269 0 0         my $sock = shift;
270             @_ == 1 ? $sock->getsockopt(SOL_SOCKET,@_)
271             : $sock->setsockopt(SOL_SOCKET,@_);
272             }
273              
274 0 0   0 1   sub atmark {
275 0           @_ == 1 or croak 'usage: $sock->atmark()';
276 0           my($sock) = @_;
277             sockatmark($sock);
278             }
279              
280 0 0 0 0 1   sub timeout {
281 0           @_ == 1 || @_ == 2 or croak 'usage: $sock->timeout([VALUE])';
282 0           my($sock,$val) = @_;
  0            
283             my $r = ${*$sock}{'io_socket_timeout'};
284 0 0          
  0 0          
285             ${*$sock}{'io_socket_timeout'} = defined $val ? 0 + $val : $val
286             if(@_ == 2);
287 0            
288             $r;
289             }
290              
291 0 0   0 1   sub sockdomain {
292 0           @_ == 1 or croak 'usage: $sock->sockdomain()';
293 0           my $sock = shift;
  0            
294             ${*$sock}{'io_socket_domain'};
295             }
296              
297 0 0   0 1   sub socktype {
298 0           @_ == 1 or croak 'usage: $sock->socktype()';
299 0           my $sock = shift;
  0            
300             ${*$sock}{'io_socket_type'}
301             }
302              
303 0 0   0 1   sub protocol {
304 0           @_ == 1 or croak 'usage: $sock->protocol()';
305 0           my($sock) = @_;
  0            
306             ${*$sock}{'io_socket_proto'};
307             }
308              
309             1;
310              
311             __END__