File Coverage

blib/lib/IO/Pipe.pm
Criterion Covered Total %
statement 79 95 83.1
branch 32 58 55.1
condition 4 14 28.5
subroutine 11 11 100.0
pod 4 4 100.0
total 130 182 71.4


line stmt bran cond sub pod time code
1             # IO::Pipe.pm
2             #
3             # Copyright (c) 1996-8 Graham Barr . All rights reserved.
4             # This program is free software; you can redistribute it and/or
5             # modify it under the same terms as Perl itself.
6              
7             package IO::Pipe;
8              
9 4     4   2090 use 5.008_001;
  4         27  
10              
11 4     4   1201 use IO::Handle;
  4         7  
  4         150  
12 4     4   19 use strict;
  4         8  
  4         59  
13 4     4   16 use Carp;
  4         8  
  4         148  
14 4     4   47 use Symbol;
  4         5  
  4         3204  
15              
16             our $VERSION = "1.49";
17              
18             sub new {
19 8     8 1 5503 my $type = shift;
20 8   50     108 my $class = ref($type) || $type || "IO::Pipe";
21 8 50 33     40 @_ == 0 || @_ == 2 or croak "usage: $class->([READFH, WRITEFH])";
22              
23 8         67 my $me = bless gensym(), $class;
24              
25 8 50       346 my($readfh,$writefh) = @_ ? @_ : $me->handles;
26              
27 8 50       315 pipe($readfh, $writefh)
28             or return undef;
29              
30 8         29 @{*$me} = ($readfh, $writefh);
  8         69  
31              
32 8         87 $me;
33             }
34              
35             sub handles {
36 8 50   8 1 33 @_ == 1 or croak 'usage: $pipe->handles()';
37 8         110 (IO::Pipe::End->new(), IO::Pipe::End->new());
38             }
39              
40             my $do_spawn = $^O eq 'os2' || $^O eq 'MSWin32';
41              
42             sub _doit {
43 5     5   13 my $me = shift;
44 5         10 my $rw = shift;
45              
46 5 50       4581 my $pid = $do_spawn ? 0 : fork();
47              
48 5 100       373 if($pid) { # Parent
    50          
49 3         137 return $pid;
50             }
51             elsif(defined $pid) { # Child or spawn
52 2         31 my $fh;
53 2 100       54 my $io = $rw ? \*STDIN : \*STDOUT;
54 2 100       70 my ($mode, $save) = $rw ? "r" : "w";
55 2 50       17 if ($do_spawn) {
56 0         0 require Fcntl;
57 0         0 $save = IO::Handle->new_from_fd($io, $mode);
58 0         0 my $handle = shift;
59             # Close in child:
60 0 0       0 unless ($^O eq 'MSWin32') {
61 0 0       0 fcntl($handle, Fcntl::F_SETFD(), 1) or croak "fcntl: $!";
62             }
63 0 0       0 $fh = $rw ? ${*$me}[0] : ${*$me}[1];
  0         0  
  0         0  
64             } else {
65 2         40 shift;
66 2 100       135 $fh = $rw ? $me->reader() : $me->writer(); # close the other end
67             }
68 2         29 bless $io, "IO::Handle";
69 2         31 $io->fdopen($fh, $mode);
70 2         20 $fh->close;
71              
72 2 50       5 if ($do_spawn) {
73 0         0 $pid = eval { system 1, @_ }; # 1 == P_NOWAIT
  0         0  
74 0         0 my $err = $!;
75            
76 0         0 $io->fdopen($save, $mode);
77 0 0       0 $save->close or croak "Cannot close $!";
78 0 0 0     0 croak "IO::Pipe: Cannot spawn-NOWAIT: $err" if not $pid or $pid < 0;
79 0         0 return $pid;
80             } else {
81 2 0       0 exec @_ or
82             croak "IO::Pipe: Cannot exec: $!";
83             }
84             }
85             else {
86 0         0 croak "IO::Pipe: Cannot fork: $!";
87             }
88              
89             # NOT Reached
90             }
91              
92             sub reader {
93 5 50   5 1 900 @_ >= 1 or croak 'usage: $pipe->reader( [SUB_COMMAND_ARGS] )';
94 5         20 my $me = shift;
95              
96             return undef
97 5 50 33     38 unless(ref($me) || ref($me = $me->new));
98              
99 5         10 my $fh = ${*$me}[0];
  5         63  
100 5         12 my $pid;
101 5 100       75 $pid = $me->_doit(0, $fh, @_)
102             if(@_);
103              
104 4         21 close ${*$me}[1];
  4         170  
105 4         147 bless $me, ref($fh);
106 4         193 *$me = *$fh; # Alias self to handle
107 4 50       184 $me->fdopen($fh->fileno,"r")
108             unless defined($me->fileno);
109 4         19 bless $fh; # Really wan't un-bless here
110 4 100       14 ${*$me}{'io_pipe_pid'} = $pid
  2         40  
111             if defined $pid;
112              
113 4         121 $me;
114             }
115              
116             sub writer {
117 5 50   5 1 1041 @_ >= 1 or croak 'usage: $pipe->writer( [SUB_COMMAND_ARGS] )';
118 5         24 my $me = shift;
119              
120             return undef
121 5 50 33     92 unless(ref($me) || ref($me = $me->new));
122              
123 5         21 my $fh = ${*$me}[1];
  5         78  
124 5         18 my $pid;
125 5 100       56 $pid = $me->_doit(1, $fh, @_)
126             if(@_);
127              
128 4         53 close ${*$me}[0];
  4         122  
129 4         134 bless $me, ref($fh);
130 4         102 *$me = *$fh; # Alias self to handle
131 4 50       137 $me->fdopen($fh->fileno,"w")
132             unless defined($me->fileno);
133 4         72 bless $fh; # Really wan't un-bless here
134 4 100       26 ${*$me}{'io_pipe_pid'} = $pid
  1         25  
135             if defined $pid;
136              
137 4         83 $me;
138             }
139              
140             package IO::Pipe::End;
141              
142             our(@ISA);
143              
144             @ISA = qw(IO::Handle);
145              
146             sub close {
147 8     8   586168 my $fh = shift;
148 8         93 my $r = $fh->SUPER::close(@_);
149              
150 3         303482 waitpid(${*$fh}{'io_pipe_pid'},0)
151 8 100       88 if(defined ${*$fh}{'io_pipe_pid'});
  8         194  
152              
153 8         68 $r;
154             }
155              
156             1;
157              
158             __END__