File Coverage

blib/lib/IPC/Run/IO.pm
Criterion Covered Total %
statement 204 209 97.6
branch 94 130 72.3
condition 28 49 57.1
subroutine 30 30 100.0
pod 12 12 100.0
total 368 430 85.5


line stmt bran cond sub pod time code
1             package IPC::Run::IO;
2              
3             =head1 NAME
4              
5             IPC::Run::IO -- I/O channels for IPC::Run.
6              
7             =head1 SYNOPSIS
8              
9             B
10             normal file descriptors; IPC::RUN::IO needs to use IPC::Run::Win32Helper
11             to do this.>
12              
13             use IPC::Run qw( io );
14              
15             ## The sense of '>' and '<' is opposite of perl's open(),
16             ## but agrees with IPC::Run.
17             $io = io( "filename", '>', \$recv );
18             $io = io( "filename", 'r', \$recv );
19              
20             ## Append to $recv:
21             $io = io( "filename", '>>', \$recv );
22             $io = io( "filename", 'ra', \$recv );
23              
24             $io = io( "filename", '<', \$send );
25             $io = io( "filename", 'w', \$send );
26              
27             $io = io( "filename", '<<', \$send );
28             $io = io( "filename", 'wa', \$send );
29              
30             ## Handles / IO objects that the caller opens:
31             $io = io( \*HANDLE, '<', \$send );
32              
33             $f = IO::Handle->new( ... ); # Any subclass of IO::Handle
34             $io = io( $f, '<', \$send );
35              
36             require IPC::Run::IO;
37             $io = IPC::Run::IO->new( ... );
38              
39             ## Then run(), harness(), or start():
40             run $io, ...;
41              
42             ## You can, of course, use io() or IPC::Run::IO->new() as an
43             ## argument to run(), harness, or start():
44             run io( ... );
45              
46             =head1 DESCRIPTION
47              
48             This class and module allows filehandles and filenames to be harnessed for
49             I/O when used IPC::Run, independent of anything else IPC::Run is doing
50             (except that errors & exceptions can affect all things that IPC::Run is
51             doing).
52              
53             =head1 SUBCLASSING
54              
55             INCOMPATIBLE CHANGE: due to the awkwardness introduced in ripping pseudohashes
56             out of Perl, this class I uses the fields pragma.
57              
58             =cut
59              
60             ## This class is also used internally by IPC::Run in a very intimate way,
61             ## since this is a partial factoring of code from IPC::Run plus some code
62             ## needed to do standalone channels. This factoring process will continue
63             ## at some point. Don't know how far how fast.
64              
65 231     231   1316 use strict;
  231         352  
  231         8673  
66 231     231   792 use warnings;
  231         556  
  231         9839  
67 231     231   873 use Carp;
  231         343  
  231         13787  
68 231     231   947 use Fcntl;
  231         303  
  231         36995  
69 231     231   1111 use Symbol;
  231         333  
  231         10428  
70              
71 231     231   946 use IPC::Run::Debug;
  231         319  
  231         12696  
72 231     231   982 use IPC::Run qw( Win32_MODE );
  231         250  
  231         14061  
73              
74 231     231   903 use vars qw{$VERSION};
  231         342  
  231         19821  
75              
76             BEGIN {
77 231     231   606 $VERSION = '20260402.0';
78 231 50       434128 if (Win32_MODE) {
79 0 0 0     0 eval "use IPC::Run::Win32Helper; require IPC::Run::Win32IO; 1"
      0        
80             or ( $@ && die )
81             or die "$!";
82             }
83             }
84              
85             sub _empty($);
86             *_empty = \&IPC::Run::_empty;
87              
88             =head1 SUBROUTINES
89              
90             =over 4
91              
92             =item new
93              
94             I think it takes >> or << along with some other data.
95              
96             TODO: Needs more thorough documentation. Patches welcome.
97              
98             =cut
99              
100             sub new {
101 9     9 1 15 my $class = shift;
102 9   33     42 $class = ref $class || $class;
103              
104 9         22 my ( $external, $type, $internal ) = ( shift, shift, pop );
105              
106 9 100       279 croak "$class: '$type' is not a valid I/O operator"
107             unless $type =~ /^(?:<>?)$/;
108              
109 8         24 my IPC::Run::IO $self = $class->_new_internal( $type, undef, undef, $internal, undef, @_ );
110              
111 8 100 33     21 if ( !ref $external ) {
    50          
112 7         15 $self->{FILENAME} = $external;
113             }
114             elsif ( ref $external eq 'GLOB' || UNIVERSAL::isa( $external, 'IO::Handle' ) ) {
115 1         3 $self->{HANDLE} = $external;
116 1         2 $self->{DONT_CLOSE} = 1;
117             }
118             else {
119 0         0 croak "$class: cannot accept " . ref($external) . " to do I/O with";
120             }
121              
122 8         28 return $self;
123             }
124              
125             ## IPC::Run uses this ctor, since it preparses things and needs more
126             ## smarts.
127             sub _new_internal {
128 4334     4334   8294 my $class = shift;
129 4334   33     16569 $class = ref $class || $class;
130              
131 4334 50 33     15973 $class = "IPC::Run::Win32IO"
132             if Win32_MODE && $class eq "IPC::Run::IO";
133              
134 4334         5476 my IPC::Run::IO $self;
135 4334         8239 $self = bless {}, $class;
136              
137 4334         15449 my ( $type, $kfd, $pty_id, $internal, $binmode, @filters ) = @_;
138              
139             # Older perls (<=5.00503, at least) don't do list assign to
140             # pseudo-hashes well.
141 4334         10359 $self->{TYPE} = $type;
142 4334         9398 $self->{KFD} = $kfd;
143 4334         8459 $self->{PTY_ID} = $pty_id;
144 4334         14052 $self->binmode($binmode);
145 4334         9616 $self->{FILTERS} = [@filters];
146              
147             ## Add an adapter to the end of the filter chain (which is usually just the
148             ## read/writer sub pushed by IPC::Run) to the DEST or SOURCE, if need be.
149 4334 100       11248 if ( $self->op =~ />/ ) {
150 2825 50       6024 croak "'$_' missing a destination" if _empty $internal;
151 2825         8730 $self->{DEST} = $internal;
152 2825 100       8908 if ( UNIVERSAL::isa( $self->{DEST}, 'CODE' ) ) {
153             ## Put a filter on the end of the filter chain to pass the
154             ## output on to the CODE ref. For SCALAR refs, the last
155             ## filter in the chain writes directly to the scalar itself. See
156             ## _init_filters(). For CODE refs, however, we need to adapt from
157             ## the SCALAR to calling the CODE.
158             unshift(
159 116         679 @{ $self->{FILTERS} },
160             sub {
161 212     212   737 my ($in_ref) = @_;
162              
163 212   66     982 return IPC::Run::input_avail() && do {
164             $self->{DEST}->($$in_ref);
165             $$in_ref = '';
166             1;
167             }
168             }
169 116         173 );
170             }
171             }
172             else {
173 1509 50       4352 croak "'$_' missing a source" if _empty $internal;
174 1509         4213 $self->{SOURCE} = $internal;
175 1509 100       7564 if ( UNIVERSAL::isa( $internal, 'CODE' ) ) {
    100          
176             push(
177 71         969 @{ $self->{FILTERS} },
178             sub {
179 88     88   625 my ( $in_ref, $out_ref ) = @_;
180 88 50       868 return 0 if length $$out_ref;
181              
182             return undef
183 88 50       420 if $self->{SOURCE_EMPTY};
184              
185             ## Call in list context so that callbacks returning
186             ## an empty array (return @a where @a is empty) are
187             ## distinguished from returning the string "0". In
188             ## scalar context both would yield 0, but an empty
189             ## list means "no more input".
190 88         670 my @in = $internal->();
191 88 100 66     1347 if ( !@in || ( @in == 1 && !defined $in[0] ) ) {
      100        
192 55         268 $self->{SOURCE_EMPTY} = 1;
193 55         963 return undef;
194             }
195 33         526 my $in = join '', @in;
196 33 100       315 return 0 unless length $in;
197 26         52 $$out_ref = $in;
198              
199 26         182 return 1;
200             }
201 71         213 );
202             }
203             elsif ( UNIVERSAL::isa( $internal, 'SCALAR' ) ) {
204             push(
205 1050         11483 @{ $self->{FILTERS} },
206             sub {
207 3059     3059   7166 my ( $in_ref, $out_ref ) = @_;
208 3059 50       10218 return 0 if length $$out_ref;
209              
210             ## pump() clears auto_close_ins, finish() sets it.
211             return $self->{HARNESS}->{auto_close_ins} ? undef : 0
212 3059         15037 if IPC::Run::_empty ${ $self->{SOURCE} }
213 3059 100 100     4625 || $self->{SOURCE_EMPTY};
    100          
214              
215             ## When clear_ins is set (start/pump mode), limit the chunk
216             ## copied per filter invocation. Without this limit, all of
217             ## $$internal is moved to the internal pipe buffer in one
218             ## shot. If the caller keeps appending to $$internal faster
219             ## than the child can consume data, the intermediate buffer
220             ## grows without bound -- exponential memory growth.
221             ## See https://github.com/cpan-authors/IPC-Run/issues/154
222 841         3325 my $max_chunk = 65536;
223 841 100 100     6990 if ( $self->{HARNESS}->{clear_ins}
224             && length($$internal) > $max_chunk )
225             {
226 14         1114 $$out_ref = substr( $$internal, 0, $max_chunk );
227 14         31 eval { substr( $$internal, 0, $max_chunk, '' ) };
  14         51  
228             ## SOURCE_EMPTY intentionally not set here: more data
229             ## remains in $$internal and will be picked up on the
230             ## next filter invocation once $$out_ref has drained.
231             }
232             else {
233 827         6122 $$out_ref = $$internal;
234 259         747 eval { $$internal = '' }
235 827 100       2817 if $self->{HARNESS}->{clear_ins};
236              
237 827         3309 $self->{SOURCE_EMPTY} = $self->{HARNESS}->{auto_close_ins};
238             }
239              
240 841         3591 return 1;
241             }
242 1050         1578 );
243             }
244             }
245              
246 4334         13365 return $self;
247             }
248              
249             =item filename
250              
251             Gets/sets the filename. Returns the value after the name change, if
252             any.
253              
254             =cut
255              
256             sub filename {
257 4     4 1 7 my IPC::Run::IO $self = shift;
258 4 50       9 $self->{FILENAME} = shift if @_;
259 4         17 return $self->{FILENAME};
260             }
261              
262             =item init
263              
264             Does initialization required before this can be run. This includes open()ing
265             the file, if necessary, and clearing the destination scalar if necessary.
266              
267             =cut
268              
269             sub init {
270 2     2 1 4 my IPC::Run::IO $self = shift;
271              
272 2         28 $self->{SOURCE_EMPTY} = 0;
273 1         3 ${ $self->{DEST} } = ''
274 2 100 66     6 if $self->mode =~ /r/ && ref $self->{DEST} eq 'SCALAR';
275              
276 2 50       6 $self->open if defined $self->filename;
277 2         8 $self->{FD} = $self->fileno;
278              
279 2 50       5 if ( !$self->{FILTERS} ) {
280 0         0 $self->{FBUFS} = undef;
281             }
282             else {
283 2         7 @{ $self->{FBUFS} } = map {
284 3         6 my $s = "";
285 3         6 \$s;
286 2         12 } ( @{ $self->{FILTERS} }, '' );
  2         6  
287              
288             $self->{FBUFS}->[0] = $self->{DEST}
289 2 100 66     11 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR';
290 2         4 push @{ $self->{FBUFS} }, $self->{SOURCE};
  2         5  
291             }
292              
293 2         6 return undef;
294             }
295              
296             =item open
297              
298             If a filename was passed in, opens it. Determines if the handle is open
299             via fileno(). Throws an exception on error.
300              
301             =cut
302              
303             my %open_flags = (
304             '>' => O_RDONLY,
305             '>>' => O_RDONLY,
306             '<' => O_WRONLY | O_CREAT | O_TRUNC,
307             '<<' => O_WRONLY | O_CREAT | O_APPEND,
308             );
309              
310             sub open {
311 2     2 1 3 my IPC::Run::IO $self = shift;
312              
313             croak "IPC::Run::IO: Can't open() a file with no name"
314 2 50       5 unless defined $self->{FILENAME};
315 2 50       10 $self->{HANDLE} = gensym unless $self->{HANDLE};
316              
317 2 50       84 _debug "opening '", $self->filename, "' mode '", $self->mode, "'"
318             if _debugging_data;
319             sysopen(
320             $self->{HANDLE},
321             $self->filename,
322 2 50       7 $open_flags{ $self->op },
323             ) or croak "IPC::Run::IO: $! opening '$self->{FILENAME}', mode '" . $self->mode . "'";
324              
325 2         7 return undef;
326             }
327              
328             =item open_pipe
329              
330             If this is a redirection IO object, this opens the pipe in a platform
331             independent manner.
332              
333             =cut
334              
335             sub _do_open {
336 3719     3719   5323 my $self = shift;
337 3719         7176 my ( $child_debug_fd, $parent_handle ) = @_;
338              
339 3719 100       7687 if ( $self->dir eq "<" ) {
340 1201 100       3375 if ( $self->{TYPE} eq '
341 63         819 ( $self->{TFD}, $self->{FD} ) = IPC::Run::_pipe;
342             }
343             else {
344 1138         7197 ( $self->{TFD}, $self->{FD} ) = IPC::Run::_pipe_nb;
345             }
346 1201 100       3870 if ($parent_handle) {
347 98 100       430 my $fh = ref $parent_handle eq 'SCALAR' ? do { require Symbol; Symbol::gensym() } : $parent_handle;
  2         24  
  2         22  
348 98 50       1637 CORE::open $fh, ">&=$self->{FD}"
349             or croak "$! duping write end of pipe for caller";
350 98 100       441 $$parent_handle = $fh if ref $parent_handle eq 'SCALAR';
351             }
352             }
353             else {
354 2518         14868 ( $self->{FD}, $self->{TFD} ) = IPC::Run::_pipe;
355 2518 100       6323 if ($parent_handle) {
356 61 100       267 my $fh = ref $parent_handle eq 'SCALAR' ? do { require Symbol; Symbol::gensym() } : $parent_handle;
  3         18  
  3         15  
357 61 50       900 CORE::open $fh, "<&=$self->{FD}"
358             or croak "$! duping read end of pipe for caller";
359 61 100       272 $$parent_handle = $fh if ref $parent_handle eq 'SCALAR';
360             }
361             }
362             }
363              
364             sub open_pipe {
365 3719     3719 1 4945 my IPC::Run::IO $self = shift;
366              
367             ## Hmmm, Maybe allow named pipes one day. But until then...
368             croak "IPC::Run::IO: Can't pipe() when a file name has been set"
369 3719 50       11492 if defined $self->{FILENAME};
370              
371 3719         13507 $self->_do_open(@_);
372              
373             ## return ( child_fd, parent_fd )
374             return $self->dir eq "<"
375             ? ( $self->{TFD}, $self->{FD} )
376 3719 100       8949 : ( $self->{FD}, $self->{TFD} );
377             }
378              
379             sub _cleanup { ## Called from Run.pm's _cleanup
380 3881     3881   4760 my $self = shift;
381 3881         16576 undef $self->{FAKE_PIPE};
382             }
383              
384             =item close
385              
386             Closes the handle. Throws an exception on failure.
387              
388              
389             =cut
390              
391             sub close {
392 3233     3233 1 4751 my IPC::Run::IO $self = shift;
393              
394 3233 100       7456 if ( defined $self->{HANDLE} ) {
395             close $self->{HANDLE}
396             or croak(
397             "IPC::Run::IO: $! closing "
398             . (
399             defined $self->{FILENAME}
400 2 0       27 ? "'$self->{FILENAME}'"
    50          
401             : "handle"
402             )
403             );
404             }
405             else {
406 3231         10023 IPC::Run::_close( $self->{FD} );
407             }
408              
409 3233         6916 $self->{FD} = undef;
410              
411 3233         5806 return undef;
412             }
413              
414             =item fileno
415              
416             Returns the fileno of the handle. Throws an exception on failure.
417              
418              
419             =cut
420              
421             sub fileno {
422 4     4 1 7 my IPC::Run::IO $self = shift;
423              
424 4         9 my $fd = fileno $self->{HANDLE};
425             croak(
426             "IPC::Run::IO: $! "
427             . (
428             defined $self->{FILENAME}
429 4 0       8 ? "'$self->{FILENAME}'"
    50          
430             : "handle"
431             )
432             ) unless defined $fd;
433              
434 4         10 return $fd;
435             }
436              
437             =item mode
438              
439             Returns the operator in terms of 'r', 'w', and 'a'. There is a state
440             'ra', unlike Perl's open(), which indicates that data read from the
441             handle or file will be appended to the output if the output is a scalar.
442             This is only meaningful if the output is a scalar, it has no effect if
443             the output is a subroutine.
444              
445             The redirection operators can be a little confusing, so here's a reference
446             table:
447              
448             > r Read from handle in to process
449             < w Write from process out to handle
450             >> ra Read from handle in to process, appending it to existing
451             data if the destination is a scalar.
452             << wa Write from process out to handle, appending to existing
453             data if IPC::Run::IO opened a named file.
454              
455             =cut
456              
457             sub mode {
458 10     10 1 14 my IPC::Run::IO $self = shift;
459              
460 10 50       19 croak "IPC::Run::IO: unexpected arguments for mode(): @_" if @_;
461              
462             ## TODO: Optimize this
463 10 100       88 return ( $self->{TYPE} =~ /{TYPE} =~ /<<|>>/ ? 'a' : '' );
    100          
464             }
465              
466             =item op
467              
468             Returns the operation: '<', '>', '<<', '>>'. See L if you want
469             to spell these 'r', 'w', etc.
470              
471             =cut
472              
473             sub op {
474 4336     4336 1 4919 my IPC::Run::IO $self = shift;
475              
476 4336 50       7609 croak "IPC::Run::IO: unexpected arguments for op(): @_" if @_;
477              
478 4336         22586 return $self->{TYPE};
479             }
480              
481             =item binmode
482              
483             Sets/gets whether this pipe is in binmode or not. No effect off of Win32
484             OSs, of course, and on Win32, no effect after the harness is start()ed.
485              
486             =cut
487              
488             sub binmode {
489 4334     4334 1 5348 my IPC::Run::IO $self = shift;
490              
491 4334 50       12726 $self->{BINMODE} = shift if @_;
492              
493 4334         6379 return $self->{BINMODE};
494             }
495              
496             =item dir
497              
498             Returns the first character of $self->op. This is either "<" or ">".
499              
500             =cut
501              
502             sub dir {
503 22728     22728 1 40883 my IPC::Run::IO $self = shift;
504              
505 22728 50       46195 croak "IPC::Run::IO: unexpected arguments for dir(): @_" if @_;
506              
507 22728         91448 return substr $self->{TYPE}, 0, 1;
508             }
509              
510             ##
511             ## Filter Scaffolding
512             ##
513             #my $filter_op ; ## The op running a filter chain right now
514             #my $filter_num; ## Which filter is being run right now.
515              
516             use vars (
517 231         106079 '$filter_op', ## The op running a filter chain right now
518             '$filter_num' ## Which filter is being run right now.
519 231     231   1666 );
  231         333  
520              
521             sub _init_filters {
522 4475     4475   148842 my IPC::Run::IO $self = shift;
523              
524 4475 50       15923 confess "\$self not an IPC::Run::IO" unless UNIVERSAL::isa( $self, "IPC::Run::IO" );
525 4475         10083 $self->{FBUFS} = [];
526              
527             $self->{FBUFS}->[0] = $self->{DEST}
528 4475 100 100     25794 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR';
529              
530 4475 100 66     14984 return unless $self->{FILTERS} && @{ $self->{FILTERS} };
  4475         13501  
531              
532 1588         3123 push @{ $self->{FBUFS} }, map {
533 3879         4517 my $s = "";
534 3879         7513 \$s;
535 1588         2219 } ( @{ $self->{FILTERS} }, '' );
  1588         3337  
536              
537 1588         2316 push @{ $self->{FBUFS} }, $self->{SOURCE};
  1588         4462  
538             }
539              
540             =item poll
541              
542             TODO: Needs confirmation that this is correct. Was previously undocumented.
543              
544             I believe this is polling the IO for new input and then returns undef if there will never be any more input, 0 if there is none now, but there might be in the future, and TRUE if more input was gotten.
545              
546             =cut
547              
548             sub poll {
549 15336     15336 1 26293 my IPC::Run::IO $self = shift;
550 15336         32878 my ($harness) = @_;
551              
552 15336 100       41788 if ( defined $self->{FD} ) {
553 15290         77969 my $d = $self->dir;
554 15290 100       51344 if ( $d eq "<" ) {
    50          
555 2076 100       8177 if ( vec $harness->{WOUT}, $self->{FD}, 1 ) {
556 1530 50       37453 _debug_desc_fd( "filtering data to", $self )
557             if _debugging_details;
558 1530         10363 return $self->_do_filters($harness);
559             }
560             }
561             elsif ( $d eq ">" ) {
562 13214 100       45537 if ( vec $harness->{ROUT}, $self->{FD}, 1 ) {
563 4217 50       91223 _debug_desc_fd( "filtering data from", $self )
564             if _debugging_details;
565 4217         20917 return $self->_do_filters($harness);
566             }
567             }
568             }
569 9589         58000 return 0;
570             }
571              
572             sub _do_filters {
573 8610     8610   216660 my IPC::Run::IO $self = shift;
574              
575 8610         30860 ( $self->{HARNESS} ) = @_;
576              
577 8610         17690 my ( $saved_op, $saved_num ) = ( $IPC::Run::filter_op, $IPC::Run::filter_num );
578 8610         16356 $IPC::Run::filter_op = $self;
579 8610         11509 $IPC::Run::filter_num = -1;
580 8610         13643 my $redos = 0;
581 8610         11656 my $r;
582             {
583 8610         10569 $@ = '';
  8610         13567  
584 8610         12923 $r = eval { IPC::Run::get_more_input(); };
  8610         29523  
585              
586             # Detect Resource temporarily unavailable and re-try 200 times (2 seconds), assuming select behaves (which it doesn't always? need ref)
587 8610 50 50     69986 if ( ( $@ || '' ) =~ $IPC::Run::_EAGAIN && $redos++ < 200 ) {
      33        
588 0         0 select( undef, undef, undef, 0.01 );
589 0         0 redo;
590             }
591             }
592 8610         20182 ( $IPC::Run::filter_op, $IPC::Run::filter_num ) = ( $saved_op, $saved_num );
593 8610         17796 $self->{HARNESS} = undef;
594 8610 50       17154 die "ack ", $@ if $@;
595 8610         44081 return $r;
596             }
597              
598             =back
599              
600             =head1 AUTHOR
601              
602             Barrie Slaymaker
603              
604             =head1 TODO
605              
606             Implement bidirectionality.
607              
608             =cut
609              
610             1;