File Coverage

blib/lib/File/FDpasser.pm
Criterion Covered Total %
statement 50 117 42.7
branch 12 68 17.6
condition 3 19 15.7
subroutine 10 15 66.6
pod 0 9 0.0
total 75 228 32.8


line stmt bran cond sub pod time code
1             package File::FDpasser;
2              
3 3     3   2624 use strict;
  3         14  
  3         127  
4 3     3   17 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $OS %ostype);
  3         5  
  3         320  
5              
6 3     3   3623 use Socket;
  3         13501  
  3         1888  
7 3     3   8064 use IO::Pipe;
  3         42233  
  3         94  
8 3     3   27 use Fcntl;
  3         5  
  3         1389  
9              
10             require Exporter;
11             require DynaLoader;
12             require AutoLoader;
13              
14             @ISA = qw(Exporter AutoLoader DynaLoader);
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18             @EXPORT = qw(
19              
20             send_file
21             recv_fd
22             recv_fh
23             serv_accept_fd
24             serv_accept_fh
25             cli_conn
26             spipe
27             endp_create
28             endp_connect
29             my_getfl
30             get_fopen_mode
31              
32             );
33              
34             @EXPORT_OK = qw(
35              
36             );
37              
38              
39              
40             $VERSION = '0.09';
41              
42             bootstrap File::FDpasser $VERSION;
43              
44             BEGIN {
45 3     3   34 %ostype=(linux=>'bsd',
46             bsdos=>'bsd',
47             netbsd=>'bsd',
48             openbsd=>'bsd',
49             freebsd=>'bsd',
50             solaris=>'svr',
51             dec_osf=>'bsd',
52             irix=>'bsd',
53             hpux=>'bsd',
54             aix=>'bsd',
55             darwin=>'bsd',
56             );
57            
58 3   50     6999 $OS=$ostype{$^O} || die "Platform $^O not supported!\n";
59             }
60              
61             sub spipe {
62 1     1 0 425 local(*RD,*WR);
63 1 50       7 if ($OS eq 'bsd') {
64 1 50       61 socketpair(RD, WR, AF_UNIX, SOCK_STREAM, PF_UNSPEC) || die "socketpair: $!\n";
65             } else {
66 0 0       0 pipe(RD,WR) || die "pipe: $!\n";
67             }
68 1         9 return (*RD{IO}, *WR{IO});
69             }
70              
71             sub endp_create {
72 1     1 0 1420 my($name)=@_;
73 1         18 my ($sck,$rem);
74 1 50       25 if ($OS eq 'bsd') {
75 1         14 local(*SCK);
76 1         30 my $uaddr = sockaddr_un($name);
77 1 50       156 socket(SCK,PF_UNIX,SOCK_STREAM,0) || return undef;
78 1         132 unlink($name);
79 1 50       100 bind(SCK, $uaddr) || return undef;
80 1 50       26 listen(SCK,SOMAXCONN) || return undef;
81 1         9 $sck=*SCK{IO};
82 1         74 $sck->autoflush();
83             } else {
84 0         0 local(*SCK,*REM);
85 0         0 pipe(SCK,REM);
86 0         0 $sck=*SCK{IO};
87 0         0 $rem=*REM{IO};
88 0         0 $sck->autoflush();
89 0         0 $rem->autoflush();
90 0         0 unlink($name);
91 0 0       0 bind_to_fs(fileno(REM),$name) || return undef;
92             }
93 1         200 return $sck;
94             }
95              
96             sub endp_connect {
97 0     0 0 0 local(*FH);
98 0         0 my($serv)=@_;
99 0 0       0 if ($OS eq 'bsd') {
100 0 0       0 socket(FH, PF_UNIX, SOCK_STREAM, PF_UNSPEC) || return undef;
101 0         0 my $sun = sockaddr_un($serv);
102 0 0       0 connect(FH,$sun) || return undef;
103             } else {
104 0 0       0 open(FH,$serv) || return undef;
105 0 0       0 if (!my_isastream(fileno(FH))) { close(FH); return undef; }
  0         0  
  0         0  
106             }
107 0         0 return *FH{IO};
108             }
109              
110             sub recv_fd {
111 0     0 0 0 my ($conn)=@_;
112 0 0       0 if (ref($conn) =~ m/^IO::/) { $conn=fileno($conn); }
  0         0  
113             # print "recv_fd: ",$conn,"\n";
114 0         0 my $fd=my_recv_fd($conn);
115             # print "recv_fd: $!\n";
116 0 0       0 if ($fd <0) { return undef; }
  0         0  
117 0         0 return $fd;
118             }
119              
120             sub recv_fh {
121 0     0 0 0 my ($conn)=@_;
122 0 0       0 if (ref($conn) =~ m/^IO::/) { $conn=fileno($conn); }
  0         0  
123             # print "recv_fh conn: $conn\n";
124 0         0 my ($fd)=my_recv_fd($conn);
125             # print "recv_fh fd: $fd\n";
126 0 0       0 if ($fd <0) { return undef; }
  0         0  
127 0         0 my $fh=IO::Handle->new();
128 0 0       0 $fh->fdopen($fd,get_fopen_mode($fd)) || return undef;
129 0         0 return $fh;
130             }
131              
132             sub send_file {
133 2     2 0 2000 my($conn,$sendfd)=@_;
134 2         29 my $fd_rc;
135 2 50       140 if (ref($conn) =~ m/^IO::/) { $conn=fileno($conn); }
  2         33  
136 2 50       35 if (ref($sendfd) =~ m/^IO::/) { $sendfd=fileno($sendfd); }
  2         8  
137 2 50 33     107 if ($conn !~ /^\d+$/ or $sendfd !~ /^\d+$/) { die "Invalid args to send_file: $_[0], $_[1]\n"; }
  0         0  
138             # print "send_file: $conn, $sendfd\n";
139 2   50     50 $fd_rc=my_send_fd($conn,$sendfd) && return undef;
140 2         23 return 1;
141             }
142              
143             sub serv_accept_fd {
144 0     0 0 0 my($lfd,$uid)=@_;
145 0 0       0 if (ref($lfd) =~ m/^IO::/) { $lfd=fileno($lfd); } else { return undef; }
  0         0  
  0         0  
146 0         0 my $fd=my_serv_accept($lfd,$uid);
147             # print "retfd: $fd\n";
148 0 0       0 if ($fd<0) { return undef; }
  0         0  
149 0         0 return $fd;
150             }
151              
152             sub serv_accept_fh {
153 1     1 0 2002670 my($LFH,$uid)=@_;
154 1         15 local(*FH);
155 1         3 my $lfd;
156 1 50       24 if (ref($LFH) =~ m/^IO::/) { $lfd=fileno($LFH); } else { return undef; }
  1         5  
  0         0  
157 1 50       83 if ($OS eq 'bsd') {
158 1 50       54 accept(FH,$LFH) || return undef;
159 1         6 return *FH{IO};
160             } else {
161 0           my $fd=my_serv_accept($lfd,$uid);
162 0 0         if ($fd <0) { return undef; }
  0            
163 0           my $fh=IO::Handle->new();
164 0 0         $fh->fdopen($fd,get_fopen_mode($fd)) || return undef;
165 0           return $fh;
166             }
167             }
168              
169             sub get_fopen_mode {
170 0     0 0   my $fd=$_[0];
171              
172 0           my $rc=my_getfl($fd);
173             # print "fd: $rc\n";
174 0 0         return undef if $rc <0;
175 0           my $acc=($rc&(O_WRONLY|O_RDONLY|O_RDWR));
176 0           my $app=($rc&O_APPEND);
177 0 0         if ($acc == O_RDONLY) { return "r"; }
  0            
178 0 0 0       if ($acc == O_WRONLY and !$app) { return "w"; }
  0            
179 0 0 0       if ($acc == O_WRONLY and $app) { return "a"; }
  0            
180 0 0 0       if ($acc == O_RDWR and !$app) { return "w+"; }
  0            
181 0 0 0       if ($acc == O_RDWR and $app) { return "a+"; }
  0            
182             }
183              
184             1;
185             __END__