File Coverage

blib/lib/IO/MultiPipe.pm
Criterion Covered Total %
statement 6 63 9.5
branch 0 12 0.0
condition n/a
subroutine 2 6 33.3
pod 4 4 100.0
total 12 85 14.1


line stmt bran cond sub pod time code
1             package IO::MultiPipe;
2              
3 1     1   57453 use IPC::Open3;
  1         8705  
  1         72  
4 1     1   13 use warnings;
  1         2  
  1         1081  
5             #use strict;
6              
7             =head1 NAME
8              
9             IO::MultiPipe - Allows for error checking on a command involving multiple pipes.
10              
11             =head1 VERSION
12              
13             Version 0.0.0
14              
15             =cut
16              
17             our $VERSION = '0.0.0';
18              
19              
20             =head1 SYNOPSIS
21              
22             Normally if a part of a pipe fails, depending on the location, it won't be
23             detected. This breaks down a command involving pipes and runs each command
24             seperately.
25              
26             It uses open3 to run each chunk of the pipe.
27              
28             use IO::MultiPipe;
29              
30             my $pipes = IO::MultiPipe->new();
31            
32             #This sets the pipe that will be run.
33             $pipes->set('sed s/-// | sed s/123/abc/ | sed s/ABC/abc/');
34             if ($pipes->{error}){
35             print "Error!\n";
36             }
37            
38             #'123-ABCxyz' through the command set above.
39             my $returned=$pipes->run('123-ABCxyz');
40              
41             =head1 FUNCTIONS
42              
43             =head2 new
44              
45             Initializes the object.
46              
47             =cut
48              
49             sub new{
50              
51 0     0 1   my $self={error=>undef, errorString=>'', pipes=>[]};
52 0           bless $self;
53              
54 0           return $self;
55             }
56              
57             =head2 run
58              
59             This runs the data through the pipe.
60              
61             =cut
62              
63             sub run{
64 0     0 1   my $self=$_[0];
65 0           my $data=$_[1];
66              
67 0           $self->errorBlank;
68              
69 0 0         if (!defined($self->{pipes}[0])) {
70 0           warn('IO-MultiPipe run:3: No command has been set yet');
71 0           $self->{error}=3;
72 0           $self->{errorString}='No command has been set yet.';
73             }
74              
75             #holds the returned data
76 0           my $returned;
77              
78             #runs each one
79 0           my $int=0;
80 0           while (defined($self->{pipes}[$int])) {
81 0           open3(PIPEWRITE, PIPEREAD, PIPEERROR, $self->{pipes}[$int]);
82 0 0         if ($?) {
83 0           warn('IO-MultiPipe run:4: Failed to open the command "'.$self->{pipes}[$int].'"');
84 0           $self->{error}=4;
85 0           $self->{errorString}='Failed to open the command "'.$self->{pipes}[$int].'"';
86 0           return undef;
87             }
88              
89             #If the int equals '0' it means this is the first path.
90 0 0         if ($int eq '0') {
91 0           print PIPEWRITE $data;
92             }else {
93 0           print PIPEWRITE $returned;
94             }
95              
96             #If we don't close it here stuff like sed will fail.
97 0           close PIPEWRITE;
98              
99             #reads the returned
100 0           $returned=join('',);
101              
102             #reads the error
103 0           my $error=join('',);
104              
105             #makes sure the command did error
106             #It will always be equal to '' because of the join
107 0 0         if ($error ne '') {
108 0           warn('IO-MultiPipe run:5: The command "'.$self->{pipes}[$int].'" failed.'.
109             ' The returned error was "'.$error.'"');
110 0           $self->{error}=5;
111 0           $self->{errorString}='The command "'.$self->{pipes}[$int].'" failed.'.
112             ' The returned error was "'.$error.'"';
113 0           return undef;
114             }
115              
116 0           close PIPEREAD;
117 0           close PIPEERROR;
118              
119 0           $int++;
120             }
121              
122 0           return $returned;
123             }
124              
125             =head2 set
126              
127             Sets the command that will be used.
128              
129             $pipes->set('sed s/-// | sed s/123/abc/ | sed s/ABC/abc/');
130             if ($pipes->{error}){
131             print "Error!\n";
132             }
133              
134             =cut
135              
136             sub set{
137 0     0 1   my $self=$_[0];
138 0           my $command=$_[1];
139              
140 0           $self->errorBlank;
141              
142 0 0         if (!defined($command)) {
143 0           warn('IO-MultiPipe set:1: No command specified');
144 0           $self->{error}=1;
145 0           $self->{errorString}='No command specified.';
146 0           return undef;
147             }
148              
149 0           my @commandSplit=split(/\|/, $command);
150              
151             #makes sure that all are defined
152 0           my $int=0;
153 0           while (defined($commandSplit[$int])) {
154             #this happens when '||' is present in a string
155 0 0         if (!defined($commandSplit[$int])) {
156 0           warn('IO-MultiPipe set:2: The command "'.$command.'" contains a null section');
157 0           $self->{error}=2;
158 0           $self->{errorString}='The command "'.$command.'" contains a null section.';
159 0           return undef;
160             }
161              
162 0           $int++;
163             }
164              
165 0           $self->{pipes}=[@commandSplit];
166              
167 0           return 1;
168             }
169              
170             =head2 errorBlank
171              
172             This blanks the error storage and is only meant for internal usage.
173              
174             It does the following.
175              
176             $self->{error}=undef;
177             $self->{errorString}="";
178              
179             =cut
180              
181             #blanks the error flags
182             sub errorBlank{
183 0     0 1   my $self=$_[0];
184              
185 0           $self->{error}=undef;
186 0           $self->{errorString}="";
187              
188 0           return 1;
189             }
190              
191             =head1 ERROR CODES
192              
193             This is contained in '$pipe->{error}'. Any time this is true,
194             there is an error.
195              
196             =head2 1
197              
198             No command passed to the set function.
199              
200             =head2 2
201              
202             Command contains null section.
203              
204             =head2 3
205              
206             No command has been set yet. The 'set' needs called first before calling 'run'.
207              
208             =head2 4
209              
210             Opening the command failed.
211              
212             =head2 5
213              
214             The command errored.
215              
216             =head1 AUTHOR
217              
218             Zane C. Bowers, C<< >>
219              
220             =head1 BUGS
221              
222             Please report any bugs or feature requests to C, or through
223             the web interface at L. I will be notified, and then you'll
224             automatically be notified of progress on your bug as I make changes.
225              
226              
227              
228              
229             =head1 SUPPORT
230              
231             You can find documentation for this module with the perldoc command.
232              
233             perldoc IO::MultiPipe
234              
235              
236             You can also look for information at:
237              
238             =over 4
239              
240             =item * RT: CPAN's request tracker
241              
242             L
243              
244             =item * AnnoCPAN: Annotated CPAN documentation
245              
246             L
247              
248             =item * CPAN Ratings
249              
250             L
251              
252             =item * Search CPAN
253              
254             L
255              
256             =back
257              
258              
259             =head1 ACKNOWLEDGEMENTS
260              
261              
262             =head1 COPYRIGHT & LICENSE
263              
264             Copyright 2008 Zane C. Bowers, all rights reserved.
265              
266             This program is free software; you can redistribute it and/or modify it
267             under the same terms as Perl itself.
268              
269              
270             =cut
271              
272             1; # End of IO::MultiPipe