File Coverage

blib/lib/Net/UNIX.pm
Criterion Covered Total %
statement 115 159 72.3
branch 56 94 59.5
condition 29 68 42.6
subroutine 18 23 78.2
pod 8 10 80.0
total 226 354 63.8


line stmt bran cond sub pod time code
1             # Copyright 1995,2002 Spider Boardman.
2             # All rights reserved.
3             #
4             # Automatic licensing for this software is available. This software
5             # can be copied and used under the terms of the GNU Public License,
6             # version 1 or (at your option) any later version, or under the
7             # terms of the Artistic license. Both of these can be found with
8             # the Perl distribution, which this software is intended to augment.
9             #
10             # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
11             # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12             # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13              
14             # rcsid: "@(#) $Id: UNIX.dat,v 1.22 2002/03/30 10:11:08 spider Exp $"
15              
16             package Net::UNIX;
17 1     1   17 use 5.004_04; # new minimum Perl version for this package
  1         3  
  1         40  
18              
19 1     1   6 use strict;
  1         2  
  1         75  
20             #use Carp;
21 0     0 0 0 sub carp { require Carp; goto &Carp::carp; }
  0         0  
22 0     0 0 0 sub croak { require Carp; goto &Carp::croak; }
  0         0  
23 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS *AUTOLOAD);
  1         2  
  1         169  
24              
25             BEGIN {
26 1     1   2 $VERSION = '1.0';
27 1     0 1 65 eval "sub Version { __PACKAGE__ . ' v$VERSION' }";
  0         0  
28             }
29              
30 1     1   1224 use AutoLoader;
  1         1787  
  1         6  
31             #use Exporter ();
32 1     1   1279 use Net::Gen 1.0 qw(/pack_sockaddr$/ :sockvals :families);
  1         41  
  1         809  
33              
34             BEGIN {
35 1     1   27 @ISA = 'Net::Gen';
36              
37             # Items to export into callers namespace by default.
38             # (Move infrequently used names to @EXPORT_OK below.)
39              
40 1         2 @EXPORT = qw(
41             );
42              
43 1         1437 @EXPORT_OK = qw(
44             pack_sockaddr_un
45             unpack_sockaddr_un
46             );
47              
48 1         7 %EXPORT_TAGS = (
49             routines => [qw(pack_sockaddr_un unpack_sockaddr_un)],
50             ALL => [@EXPORT, @EXPORT_OK],
51             );
52 1         2279 *AUTOLOAD = \$Net::Gen::AUTOLOAD;
53             }
54              
55             ;# sub AUTOLOAD inherited from Net::Gen
56              
57             ;# since 5.003_96 will break simple subroutines with inherited autoload, cheat
58             sub AUTOLOAD
59             {
60             #$Net::Gen::AUTOLOAD = $AUTOLOAD;
61 1     1   5 goto &Net::Gen::AUTOLOAD;
62             }
63              
64              
65             # Preloaded methods go here. Autoload methods go after __END__, and are
66             # processed by the autosplit program.
67              
68             ;# No additional sockopts for UNIX-domain sockets (?)
69              
70             my $sun_path_len =
71             length(Socket::unpack_sockaddr_un(Socket::pack_sockaddr_un('')));
72              
73             #& _canonpath($path) : returns NUL-padded $path for sun_addr
74             sub _canonpath ($)
75             {
76 10     10   17 my $path = shift;
77 10         13 my $ix;
78             # extend to proper length
79 10         27 $ix = index($path, "\0");
80 10 100       19 if ($ix >= 0) {
81 5 50       38 substr($path,$ix) = "\0" x ($sun_path_len - $ix)
82             if $ix < $sun_path_len;
83             }
84             else {
85 5         9 $ix = length($path);
86 5 50       12 if ($ix < $sun_path_len) {
87 5         19 $path .= "\0" x ($sun_path_len - $ix);
88             }
89             else {
90 0         0 $path .= "\0";
91             }
92             }
93 10         64 $path;
94             }
95              
96             #& pack_sockaddr_un([$family,] $path) : $packed_addr
97             sub pack_sockaddr_un ($;$)
98             {
99 5     5 1 13 my(@args) = @_;
100 5 50       15 unshift(@args, AF_UNIX) if @args == 1;
101 5         16 pack_sockaddr($args[0], _canonpath($args[1]));
102             }
103              
104             #& unpack_sockaddr_un($sockaddr_un) : [$fam,] $path
105             sub unpack_sockaddr_un ($)
106             {
107 0     0 1 0 my $addr = shift;
108 0         0 my ($fam,$path) = unpack_sockaddr($addr);
109 0         0 my $nul = index($path, "\0");
110 0 0       0 if ($nul >= 0) {
111 0         0 substr($path, $nul) = '';
112             }
113 0   0     0 $fam ||= AF_UNIX;
114 0 0       0 wantarray ? ($fam, $path) : $path;
115             }
116              
117             my $debug = 0;
118              
119             #& _debug($this, [$newval]) : oldval
120             sub _debug : locked
121             {
122 142     142   318 my ($this,$newval) = @_;
123 142 100       522 return $this->debug($newval) if ref $this;
124 18         22 my $prev = $debug;
125 18 50       39 $debug = 0+$newval if defined $newval;
126 18         88 $prev;
127             }
128              
129              
130             my %keyhandlers = (thispath => \&_setbindpath,
131             destpath => \&_setconnpath,
132             unbuffered_IO => \&_setbuf_unbuf,
133             unbuffered_io => \&_setbuf_unbuf,
134             );
135              
136             my @Keys = qw(unbuffered_input unbuffered_output);
137              
138             my %Keys; # for storing the registrations
139              
140              
141             #& new($class, [\%params]) : {$obj | undef}
142             sub new : locked
143             {
144 5     5 1 1613 my $whoami = $_[0]->_trace(\@_,1);
145 5         16 my($class,@Args,$self) = @_;
146 5         36 $self = $class->SUPER::new(@Args);
147 5 100       14 $class = ref $class if ref $class;
148 5 50 33     51 ($self || $class)->_trace(\@_,2,", self" .
149             (defined $self ? "=$self" : " undefined") .
150             " after sub-new");
151 5 50       14 if ($self) {
152             # register our keys and their handlers
153 5 100       12 if (%Keys) {
154 4         76 $ {*$self}{Keys} = { %Keys };
  4         13  
155             }
156             else {
157 1 50       5 $self->register_param_keys(\@Keys) if @Keys;
158 1         23 $self->register_param_handlers(\%keyhandlers);
159 1         2 %Keys = %{ $ {*$self}{Keys} };
  1         2  
  1         16  
160             }
161             # register our socket options
162             # none for AF_UNIX?
163             # set our expected parameters
164 5         66 $self->setparams({PF => PF_UNIX, AF => AF_UNIX,
165             unbuffered_output => 0,
166             unbuffered_input => 0,
167             type => SOCK_DGRAM},
168             -1);
169 5 100       26 if ($class eq __PACKAGE__) {
170 2 50       12 unless ($self->init(@Args)) {
171 0         0 local $!; # protect errno
172 0         0 undef $self; # from the side-effects of this
173 0         0 undef $self; # another statement needed for unwinding
174             }
175             }
176             }
177 5 50       39 if ($debug) {
178 0 0       0 if ($self) {
179 0         0 print STDERR __PACKAGE__ . "::new returning self=$self\n";
180             }
181             else {
182 0         0 print STDERR __PACKAGE__ . "::new returning undef\n";
183             }
184             }
185 5         22 $self;
186             }
187              
188             #& _setbindpath($self, 'thispath', $path) : {'' | "carp string"}
189             sub _setbindpath
190             {
191 3     3   8 my($self,$what,$path) = @_;
192 3         5 my $ix;
193 3 50       9 if (!defined($path)) {
194             # removing, so cooperate
195 0         0 delete $ {*$self}{Parms}{srcaddrlist};
  0         0  
196 0         0 return '';
197             }
198             # canonicalize the path to be of the right length, if possible
199 3         12 $path = _canonpath($path);
200 3         8 $ix = index($path, "\0"); # check for NUL-termination
201 3 50       7 if (!$ix) { # empty path is not a bind
202 0         0 delete $ {*$self}{Parms}{srcaddrlist};
  0         0  
203 0         0 $_[2] = undef;
204             }
205             else {
206 3         19 $ {*$self}{Parms}{srcaddrlist} =
  3         12  
207             [pack_sockaddr_un($self->getparam('AF',AF_UNIX,1), $path)];
208             }
209 3         19 '';
210             }
211              
212             #& _setconnpath($self, 'destpath', $path) : {'' | "carp string"}
213             sub _setconnpath
214             {
215 2     2   5 my($self,$what,$path) = @_;
216 2         4 my $ix;
217 2 50       6 if (!defined($path)) {
218             # removing, so cooperate
219 0         0 delete $ {*$self}{Parms}{dstaddrlist};
  0         0  
220 0         0 return '';
221             }
222             # canonicalize the path to be of the right length, if possible
223 2         9 $path = _canonpath($path);
224 2         4 $ix = index($path, "\0"); # check for NUL-termination
225 2 50       26 if (!$ix) { # empty path?
226 0         0 "$what parameter has no path: $path";
227             }
228             else { # just try it here
229 2         14 $ {*$self}{Parms}{dstaddrlist} =
  2         7  
230             [pack_sockaddr_un($self->getparam('AF',AF_UNIX,1), $path)];
231 2         9 '';
232             }
233             }
234              
235             #& _init($self, whatpath[, $path][, \%params]) : {$self | undef}
236             sub _init : locked method
237             {
238 5     5   19 my ($self,$what,@args,$path,$parms) = @_;
239 5 100 100     26 if (@args == 1 or @args == 2) {
240 4         9 $parms = $args[-1];
241 4 100 66     24 $parms = undef
242             unless $parms and ref($parms) eq 'HASH';
243 4         7 $path = $args[0];
244 4 100 66     21 $path = undef
245             if defined($path) and ref($path);
246             }
247 5 50 66     61 croak("Invalid call to " . __PACKAGE__ . "::init(@_)")
      33        
      33        
248             if @args == 2 and !$parms or @args > 2 or !$what;
249 5   100     19 $parms ||= {};
250 5 100       21 $$parms{$what} = $path if defined $path;
251 5 50       27 return undef unless $self->SUPER::init($parms);
252 5 100       16 if (scalar %$parms) {
253 4 50       15 return undef unless $self->setparams($parms);
254             }
255 5 100       22 $self->setparams({netgen_fakeconnect=>1},-1) if
256             $self->getparam('type') == SOCK_DGRAM;
257 5 100       41 if ($self->getparams([qw(srcaddr srcaddrlist dstaddr dstaddrlist)],1) >0) {
258 3 50 33     10 return undef unless $self->isopen or $self->open;
259 3 100       17 if ($self->getparams([qw(srcaddr srcaddrlist)],1) > 0) {
260 2 50 33     18 return undef unless $self->isbound or $self->bind;
261             }
262 3 100       23 if ($self->getparams([qw(dstaddr dstaddrlist)],1) > 0) {
263 1 0 33     9 return undef unless $self->isconnected or $self->connect or
      0        
      33        
264             $self->isconnecting and !$self->blocking;
265             }
266             }
267 5         35 $self;
268             }
269              
270             #& init($self [, $destpath][, \%params]) : {$self | undef}
271             sub init
272             {
273 2     2 1 7 my ($self,@args) = @_;
274 2         8 $self->_init('destpath',@args);
275             }
276              
277             #& connect($self [, $destpath] [, \%newparams]) : boolean
278             sub connect : locked method
279             {
280 2     2 1 718 my($self,$path,$parms) = @_;
281 2 50 33     24 if (@_ > 3 or @_ == 3 and (!ref($parms) or ref($path))) {
      66        
      33        
282 0         0 croak("Invalid arguments to " . __PACKAGE__ . "::connect(@_), called");
283             }
284 2 50 33     10 if (@_ == 2 and ref $path) {
285 0         0 $parms = $path;
286 0         0 undef $path;
287             }
288             else {
289 2   100     9 $parms ||= {};
290             }
291 2 100       7 if (defined $path) {
292 1         3 $$parms{destpath} = $path;
293             }
294 2 100       16 if (@_ > 1) {
295 1 50       6 return unless $self->setparams($parms);
296             }
297 2         14 $self->SUPER::connect;
298             }
299              
300             #& format_addr({$class|$obj} , $sockaddr) : $string
301             sub format_addr
302             {
303 0     0 1 0 my ($this,$addr) = @_;
304 0         0 my ($fam,$sdata) = unpack_sockaddr($addr);
305 0 0       0 if ($fam == AF_UNIX) {
306 0         0 $sdata = unpack_sockaddr_un($addr);
307             }
308             else {
309 0         0 $sdata = $this->SUPER::format_addr($addr);
310             }
311 0         0 $sdata;
312             }
313              
314             1;
315              
316              
317             # autoloaded methods go after the END token (& pod) below
318              
319             __END__