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   1868 use 5.008_001;
  4         24  
10              
11 4     4   3358 use IO::Handle;
  4         11  
  4         146  
12 4     4   19 use strict;
  4         5  
  4         73  
13 4     4   17 use Carp;
  4         4  
  4         149  
14 4     4   15 use Symbol;
  4         8  
  4         3161  
15              
16             our $VERSION = "1.51";
17              
18             sub new {
19 8     8 1 5371 my $type = shift;
20 8   50     121 my $class = ref($type) || $type || "IO::Pipe";
21 8 50 33     39 @_ == 0 || @_ == 2 or croak "usage: $class->([READFH, WRITEFH])";
22              
23 8         63 my $me = bless gensym(), $class;
24              
25 8 50       274 my($readfh,$writefh) = @_ ? @_ : $me->handles;
26              
27 8 50       266 pipe($readfh, $writefh)
28             or return undef;
29              
30 8         23 @{*$me} = ($readfh, $writefh);
  8         62  
31              
32 8         68 $me;
33             }
34              
35             sub handles {
36 8 50   8 1 25 @_ == 1 or croak 'usage: $pipe->handles()';
37 8         102 (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   12 my $me = shift;
44 5         8 my $rw = shift;
45              
46 5 50       4190 my $pid = $do_spawn ? 0 : fork();
47              
48 5 100       308 if($pid) { # Parent
    50          
49 3         116 return $pid;
50             }
51             elsif(defined $pid) { # Child or spawn
52 2         28 my $fh;
53 2 100       45 my $io = $rw ? \*STDIN : \*STDOUT;
54 2 100       35 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         16 shift;
66 2 100       71 $fh = $rw ? $me->reader() : $me->writer(); # close the other end
67             }
68 2         19 bless $io, "IO::Handle";
69 2         37 $io->fdopen($fh, $mode);
70 2         26 $fh->close;
71              
72 2 50       6 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 899 @_ >= 1 or croak 'usage: $pipe->reader( [SUB_COMMAND_ARGS] )';
94 5         15 my $me = shift;
95              
96             return undef
97 5 50 33     37 unless(ref($me) || ref($me = $me->new));
98              
99 5         5 my $fh = ${*$me}[0];
  5         60  
100 5         10 my $pid;
101 5 100       18 $pid = $me->_doit(0, $fh, @_)
102             if(@_);
103              
104 4         18 close ${*$me}[1];
  4         143  
105 4         148 bless $me, ref($fh);
106 4         164 *$me = *$fh; # Alias self to handle
107 4 50       164 $me->fdopen($fh->fileno,"r")
108             unless defined($me->fileno);
109 4         8 bless $fh; # Really wan't un-bless here
110 4 100       35 ${*$me}{'io_pipe_pid'} = $pid
  2         48  
111             if defined $pid;
112              
113 4         74 $me;
114             }
115              
116             sub writer {
117 5 50   5 1 694 @_ >= 1 or croak 'usage: $pipe->writer( [SUB_COMMAND_ARGS] )';
118 5         23 my $me = shift;
119              
120             return undef
121 5 50 33     76 unless(ref($me) || ref($me = $me->new));
122              
123 5         23 my $fh = ${*$me}[1];
  5         79  
124 5         9 my $pid;
125 5 100       57 $pid = $me->_doit(1, $fh, @_)
126             if(@_);
127              
128 4         51 close ${*$me}[0];
  4         103  
129 4         109 bless $me, ref($fh);
130 4         82 *$me = *$fh; # Alias self to handle
131 4 50       145 $me->fdopen($fh->fileno,"w")
132             unless defined($me->fileno);
133 4         13 bless $fh; # Really wan't un-bless here
134 4 100       49 ${*$me}{'io_pipe_pid'} = $pid
  1         15  
135             if defined $pid;
136              
137 4         85 $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   567718 my $fh = shift;
148 8         69 my $r = $fh->SUPER::close(@_);
149              
150 3         279773 waitpid(${*$fh}{'io_pipe_pid'},0)
151 8 100       56 if(defined ${*$fh}{'io_pipe_pid'});
  8         87  
152              
153 8         41 $r;
154             }
155              
156             1;
157              
158             __END__