5 IPC::Run::IO -- I/O channels for IPC::Run.
9 B<NOT IMPLEMENTED YET ON Win32! Win32 does not allow select() on
10 normal file descriptors; IPC::RUN::IO needs to use IPC::Run::Win32Helper
13 use IPC::Run qw( io ) ;
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 ) ;
21 $io = io( "filename", '>>', \$recv ) ;
22 $io = io( "filename", 'ra', \$recv ) ;
24 $io = io( "filename", '<', \$send ) ;
25 $io = io( "filename", 'w', \$send ) ;
27 $io = io( "filename", '<<', \$send ) ;
28 $io = io( "filename", 'wa', \$send ) ;
30 ## Handles / IO objects that the caller opens:
31 $io = io( \*HANDLE, '<', \$send ) ;
33 $f = IO::Handle->new( ... ) ; # Any subclass of IO::Handle
34 $io = io( $f, '<', \$send ) ;
36 require IPC::Run::IO ;
37 $io = IPC::Run::IO->new( ... ) ;
39 ## Then run(), harness(), or start():
42 ## You can, of course, use io() or IPC::Run::IO->new() as an
43 ## argument to run(), harness, or start():
49 This class and module allows filehandles and filenames to be harnessed for
50 I/O when used IPC::Run, independant of anything else IPC::Run is doing
51 (except that errors & exceptions can affect all things that IPC::Run is
56 INCOMPATIBLE CHANGE: due to the awkwardness introduced in ripping pseudohashes
57 out of Perl, this class I<no longer> uses the fields pragma.
61 Implement bidirectionality.
65 Barrie Slaymaker <barries@slaysys.com>
69 ## This class is also used internally by IPC::Run in a very initimate way,
70 ## since this is a partial factoring of code from IPC::Run plus some code
71 ## needed to do standalone channels. This factoring process will continue
72 ## at some point. Don't know how far how fast.
78 use UNIVERSAL qw( isa ) ;
81 use IPC::Run qw( Win32_MODE );
85 eval "use IPC::Run::Win32Helper; require IPC::Run::Win32IO; 1"
86 or ( $@ && die ) or die "$!" ;
92 *_empty = \&IPC::Run::_empty ;
97 $class = ref $class || $class ;
99 my ( $external, $type, $internal ) = ( shift, shift, pop ) ;
101 croak "$class: '$_' is not a valid I/O operator"
102 unless $type =~ /^(?:<<?|>>?)$/ ;
104 my IPC::Run::IO $self = $class->_new_internal(
105 $type, undef, undef, $internal, undef, @_
108 if ( ! ref $external ) {
109 $self->{FILENAME} = $external ;
111 elsif ( ref eq 'GLOB' || isa( $external, 'IO::Handle' ) ) {
112 $self->{HANDLE} = $external ;
113 $self->{DONT_CLOSE} = 1 ;
116 croak "$class: cannot accept " . ref( $external ) . " to do I/O with" ;
123 ## IPC::Run uses this ctor, since it preparses things and needs more
127 $class = ref $class || $class ;
129 $class = "IPC::Run::Win32IO"
130 if Win32_MODE && $class eq "IPC::Run::IO";
132 my IPC::Run::IO $self ;
133 $self = bless {}, $class ;
135 my ( $type, $kfd, $pty_id, $internal, $binmode, @filters ) = @_ ;
137 # Older perls (<=5.00503, at least) don't do list assign to
138 # psuedo-hashes well.
139 $self->{TYPE} = $type ;
140 $self->{KFD} = $kfd ;
141 $self->{PTY_ID} = $pty_id ;
142 $self->binmode( $binmode ) ;
143 $self->{FILTERS} = [ @filters ] ;
145 ## Add an adapter to the end of the filter chain (which is usually just the
146 ## read/writer sub pushed by IPC::Run) to the DEST or SOURCE, if need be.
147 if ( $self->op =~ />/ ) {
148 croak "'$_' missing a destination" if _empty $internal ;
149 $self->{DEST} = $internal ;
150 if ( isa( $self->{DEST}, 'CODE' ) ) {
151 ## Put a filter on the end of the filter chain to pass the
152 ## output on to the CODE ref. For SCALAR refs, the last
153 ## filter in the chain writes directly to the scalar itself. See
154 ## _init_filters(). For CODE refs, however, we need to adapt from
155 ## the SCALAR to calling the CODE.
159 my ( $in_ref ) = @_ ;
161 return IPC::Run::input_avail() && do {
162 $self->{DEST}->( $$in_ref ) ;
171 croak "'$_' missing a source" if _empty $internal ;
172 $self->{SOURCE} = $internal ;
173 if ( isa( $internal, 'CODE' ) ) {
177 my ( $in_ref, $out_ref ) = @_ ;
178 return 0 if length $$out_ref ;
181 if $self->{SOURCE_EMPTY} ;
183 my $in = $internal->() ;
184 unless ( defined $in ) {
185 $self->{SOURCE_EMPTY} = 1 ;
188 return 0 unless length $in ;
195 elsif ( isa( $internal, 'SCALAR' ) ) {
199 my ( $in_ref, $out_ref ) = @_ ;
200 return 0 if length $$out_ref ;
202 ## pump() clears auto_close_ins, finish() sets it.
203 return $self->{HARNESS}->{auto_close_ins} ? undef : 0
204 if IPC::Run::_empty ${$self->{SOURCE}}
205 || $self->{SOURCE_EMPTY} ;
207 $$out_ref = $$internal ;
208 eval { $$internal = '' }
209 if $self->{HARNESS}->{clear_ins} ;
211 $self->{SOURCE_EMPTY} = $self->{HARNESS}->{auto_close_ins} ;
225 Gets/sets the filename. Returns the value after the name change, if
231 my IPC::Run::IO $self = shift ;
232 $self->{FILENAME} = shift if @_ ;
233 return $self->{FILENAME} ;
239 Does initialization required before this can be run. This includes open()ing
240 the file, if necessary, and clearing the destination scalar if necessary.
245 my IPC::Run::IO $self = shift ;
247 $self->{SOURCE_EMPTY} = 0 ;
248 ${$self->{DEST}} = ''
249 if $self->mode =~ /r/ && ref $self->{DEST} eq 'SCALAR' ;
251 $self->open if defined $self->filename ;
252 $self->{FD} = $self->fileno ;
254 if ( ! $self->{FILTERS} ) {
255 $self->{FBUFS} = undef ;
258 @{$self->{FBUFS}} = map {
261 } ( @{$self->{FILTERS}}, '' ) ;
263 $self->{FBUFS}->[0] = $self->{DEST}
264 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR' ;
265 push @{$self->{FBUFS}}, $self->{SOURCE} ;
274 If a filename was passed in, opens it. Determines if the handle is open
275 via fileno(). Throws an exception on error.
282 '<' => O_WRONLY | O_CREAT | O_TRUNC,
283 '<<' => O_WRONLY | O_CREAT | O_APPEND,
287 my IPC::Run::IO $self = shift ;
289 croak "IPC::Run::IO: Can't open() a file with no name"
290 unless defined $self->{FILENAME} ;
291 $self->{HANDLE} = gensym unless $self->{HANDLE} ;
294 "opening '", $self->filename, "' mode '", $self->mode, "'"
299 $open_flags{$self->op},
301 "IPC::Run::IO: $! opening '$self->{FILENAME}', mode '" . $self->mode . "'" ;
309 If this is a redirection IO object, this opens the pipe in a platform
316 my ( $child_debug_fd, $parent_handle ) = @_ ;
319 if ( $self->dir eq "<" ) {
320 ( $self->{TFD}, $self->{FD} ) = IPC::Run::_pipe_nb ;
321 if ( $parent_handle ) {
322 CORE::open $parent_handle, ">&=$self->{FD}"
323 or croak "$! duping write end of pipe for caller" ;
327 ( $self->{FD}, $self->{TFD} ) = IPC::Run::_pipe ;
328 if ( $parent_handle ) {
329 CORE::open $parent_handle, "<&=$self->{FD}"
330 or croak "$! duping read end of pipe for caller" ;
336 my IPC::Run::IO $self = shift ;
338 ## Hmmm, Maybe allow named pipes one day. But until then...
339 croak "IPC::Run::IO: Can't pipe() when a file name has been set"
340 if defined $self->{FILENAME} ;
342 $self->_do_open( @_ );
344 ## return ( child_fd, parent_fd )
345 return $self->dir eq "<"
346 ? ( $self->{TFD}, $self->{FD} )
347 : ( $self->{FD}, $self->{TFD} ) ;
351 sub _cleanup { ## Called from Run.pm's _cleanup
353 undef $self->{FAKE_PIPE};
359 Closes the handle. Throws an exception on failure.
365 my IPC::Run::IO $self = shift ;
367 if ( defined $self->{HANDLE} ) {
368 close $self->{HANDLE}
369 or croak( "IPC::Run::IO: $! closing "
370 . ( defined $self->{FILENAME}
371 ? "'$self->{FILENAME}'"
377 IPC::Run::_close( $self->{FD} ) ;
380 $self->{FD} = undef ;
387 Returns the fileno of the handle. Throws an exception on failure.
393 my IPC::Run::IO $self = shift ;
395 my $fd = fileno $self->{HANDLE} ;
396 croak( "IPC::Run::IO: $! "
397 . ( defined $self->{FILENAME}
398 ? "'$self->{FILENAME}'"
401 ) unless defined $fd ;
408 Returns the operator in terms of 'r', 'w', and 'a'. There is a state
409 'ra', unlike Perl's open(), which indicates that data read from the
410 handle or file will be appended to the output if the output is a scalar.
411 This is only meaningful if the output is a scalar, it has no effect if
412 the output is a subroutine.
414 The redirection operators can be a little confusing, so here's a reference
417 > r Read from handle in to process
418 < w Write from process out to handle
419 >> ra Read from handle in to process, appending it to existing
420 data if the destination is a scalar.
421 << wa Write from process out to handle, appending to existing
422 data if IPC::Run::IO opened a named file.
427 my IPC::Run::IO $self = shift ;
429 croak "IPC::Run::IO: unexpected arguments for mode(): @_" if @_ ;
431 ## TODO: Optimize this
432 return ( $self->{TYPE} =~ /</ ? 'w' : 'r' ) .
433 ( $self->{TYPE} =~ /<<|>>/ ? 'a' : '' ) ;
439 Returns the operation: '<', '>', '<<', '>>'. See L</mode> if you want
440 to spell these 'r', 'w', etc.
445 my IPC::Run::IO $self = shift ;
447 croak "IPC::Run::IO: unexpected arguments for op(): @_" if @_ ;
449 return $self->{TYPE} ;
454 Sets/gets whether this pipe is in binmode or not. No effect off of Win32
455 OSs, of course, and on Win32, no effect after the harness is start()ed.
460 my IPC::Run::IO $self = shift ;
462 $self->{BINMODE} = shift if @_ ;
464 return $self->{BINMODE} ;
470 Returns the first character of $self->op. This is either "<" or ">".
475 my IPC::Run::IO $self = shift ;
477 croak "IPC::Run::IO: unexpected arguments for dir(): @_" if @_ ;
479 return substr $self->{TYPE}, 0, 1 ;
484 ## Filter Scaffolding
486 #my $filter_op ; ## The op running a filter chain right now
487 #my $filter_num ; ## Which filter is being run right now.
490 '$filter_op', ## The op running a filter chain right now
491 '$filter_num' ## Which filter is being run right now.
495 my IPC::Run::IO $self = shift ;
497 confess "\$self not an IPC::Run::IO" unless isa( $self, "IPC::Run::IO" ) ;
498 $self->{FBUFS} = [] ;
500 $self->{FBUFS}->[0] = $self->{DEST}
501 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR' ;
503 return unless $self->{FILTERS} && @{$self->{FILTERS}} ;
505 push @{$self->{FBUFS}}, map {
508 } ( @{$self->{FILTERS}}, '' ) ;
510 push @{$self->{FBUFS}}, $self->{SOURCE} ;
515 my IPC::Run::IO $self = shift;
516 my ( $harness ) = @_;
518 if ( defined $self->{FD} ) {
521 if ( vec $harness->{WOUT}, $self->{FD}, 1 ) {
522 _debug_desc_fd( "filtering data to", $self )
523 if _debugging_details ;
524 return $self->_do_filters( $harness );
527 elsif ( $d eq ">" ) {
528 if ( vec $harness->{ROUT}, $self->{FD}, 1 ) {
529 _debug_desc_fd( "filtering data from", $self )
530 if _debugging_details ;
531 return $self->_do_filters( $harness );
540 my IPC::Run::IO $self = shift ;
542 ( $self->{HARNESS} ) = @_ ;
544 my ( $saved_op, $saved_num ) =($IPC::Run::filter_op,$IPC::Run::filter_num) ;
545 $IPC::Run::filter_op = $self ;
546 $IPC::Run::filter_num = -1 ;
551 $r = eval { IPC::Run::get_more_input() ; } ;
553 ##$@ and warn "redo ", substr($@, 0, 20) , " ";
554 (($c < 200) and ($@||'')=~ m/^Resource temporarily/) and redo;
556 ( $IPC::Run::filter_op, $IPC::Run::filter_num ) = ( $saved_op, $saved_num ) ;
557 $self->{HARNESS} = undef ;
558 die "ack ", $@ if $@ ;