7 IPC::Run::IO -- I/O channels for IPC::Run.
11 B<NOT IMPLEMENTED YET ON Win32! Win32 does not allow select() on
12 normal file descriptors; IPC::RUN::IO needs to use IPC::Run::Win32Helper
15 use IPC::Run qw( io );
17 ## The sense of '>' and '<' is opposite of perl's open(),
18 ## but agrees with IPC::Run.
19 $io = io( "filename", '>', \$recv );
20 $io = io( "filename", 'r', \$recv );
23 $io = io( "filename", '>>', \$recv );
24 $io = io( "filename", 'ra', \$recv );
26 $io = io( "filename", '<', \$send );
27 $io = io( "filename", 'w', \$send );
29 $io = io( "filename", '<<', \$send );
30 $io = io( "filename", 'wa', \$send );
32 ## Handles / IO objects that the caller opens:
33 $io = io( \*HANDLE, '<', \$send );
35 $f = IO::Handle->new( ... ); # Any subclass of IO::Handle
36 $io = io( $f, '<', \$send );
39 $io = IPC::Run::IO->new( ... );
41 ## Then run(), harness(), or start():
44 ## You can, of course, use io() or IPC::Run::IO->new() as an
45 ## argument to run(), harness, or start():
50 This class and module allows filehandles and filenames to be harnessed for
51 I/O when used IPC::Run, independant of anything else IPC::Run is doing
52 (except that errors & exceptions can affect all things that IPC::Run is
57 INCOMPATIBLE CHANGE: due to the awkwardness introduced in ripping pseudohashes
58 out of Perl, this class I<no longer> uses the fields pragma.
62 Implement bidirectionality.
66 Barrie Slaymaker <barries@slaysys.com>
70 ## This class is also used internally by IPC::Run in a very initimate way,
71 ## since this is a partial factoring of code from IPC::Run plus some code
72 ## needed to do standalone channels. This factoring process will continue
73 ## at some point. Don't know how far how fast.
82 use IPC::Run qw( Win32_MODE );
84 use vars qw{$VERSION};
88 eval "use IPC::Run::Win32Helper; require IPC::Run::Win32IO; 1"
89 or ( $@ && die ) or die "$!";
94 *_empty = \&IPC::Run::_empty;
98 $class = ref $class || $class;
100 my ( $external, $type, $internal ) = ( shift, shift, pop );
102 croak "$class: '$_' is not a valid I/O operator"
103 unless $type =~ /^(?:<<?|>>?)$/;
105 my IPC::Run::IO $self = $class->_new_internal(
106 $type, undef, undef, $internal, undef, @_
109 if ( ! ref $external ) {
110 $self->{FILENAME} = $external;
112 elsif ( ref eq 'GLOB' || UNIVERSAL::isa( $external, 'IO::Handle' ) ) {
113 $self->{HANDLE} = $external;
114 $self->{DONT_CLOSE} = 1;
117 croak "$class: cannot accept " . ref( $external ) . " to do I/O with";
124 ## IPC::Run uses this ctor, since it preparses things and needs more
128 $class = ref $class || $class;
130 $class = "IPC::Run::Win32IO"
131 if Win32_MODE && $class eq "IPC::Run::IO";
133 my IPC::Run::IO $self;
134 $self = bless {}, $class;
136 my ( $type, $kfd, $pty_id, $internal, $binmode, @filters ) = @_;
138 # Older perls (<=5.00503, at least) don't do list assign to
139 # psuedo-hashes well.
140 $self->{TYPE} = $type;
142 $self->{PTY_ID} = $pty_id;
143 $self->binmode( $binmode );
144 $self->{FILTERS} = [ @filters ];
146 ## Add an adapter to the end of the filter chain (which is usually just the
147 ## read/writer sub pushed by IPC::Run) to the DEST or SOURCE, if need be.
148 if ( $self->op =~ />/ ) {
149 croak "'$_' missing a destination" if _empty $internal;
150 $self->{DEST} = $internal;
151 if ( UNIVERSAL::isa( $self->{DEST}, 'CODE' ) ) {
152 ## Put a filter on the end of the filter chain to pass the
153 ## output on to the CODE ref. For SCALAR refs, the last
154 ## filter in the chain writes directly to the scalar itself. See
155 ## _init_filters(). For CODE refs, however, we need to adapt from
156 ## the SCALAR to calling the CODE.
162 return IPC::Run::input_avail() && do {
163 $self->{DEST}->( $$in_ref );
172 croak "'$_' missing a source" if _empty $internal;
173 $self->{SOURCE} = $internal;
174 if ( UNIVERSAL::isa( $internal, 'CODE' ) ) {
178 my ( $in_ref, $out_ref ) = @_;
179 return 0 if length $$out_ref;
182 if $self->{SOURCE_EMPTY};
184 my $in = $internal->();
185 unless ( defined $in ) {
186 $self->{SOURCE_EMPTY} = 1;
189 return 0 unless length $in;
196 elsif ( UNIVERSAL::isa( $internal, 'SCALAR' ) ) {
200 my ( $in_ref, $out_ref ) = @_;
201 return 0 if length $$out_ref;
203 ## pump() clears auto_close_ins, finish() sets it.
204 return $self->{HARNESS}->{auto_close_ins} ? undef : 0
205 if IPC::Run::_empty ${$self->{SOURCE}}
206 || $self->{SOURCE_EMPTY};
208 $$out_ref = $$internal;
209 eval { $$internal = '' }
210 if $self->{HARNESS}->{clear_ins};
212 $self->{SOURCE_EMPTY} = $self->{HARNESS}->{auto_close_ins};
229 Gets/sets the filename. Returns the value after the name change, if
235 my IPC::Run::IO $self = shift;
236 $self->{FILENAME} = shift if @_;
237 return $self->{FILENAME};
244 Does initialization required before this can be run. This includes open()ing
245 the file, if necessary, and clearing the destination scalar if necessary.
250 my IPC::Run::IO $self = shift;
252 $self->{SOURCE_EMPTY} = 0;
253 ${$self->{DEST}} = ''
254 if $self->mode =~ /r/ && ref $self->{DEST} eq 'SCALAR';
256 $self->open if defined $self->filename;
257 $self->{FD} = $self->fileno;
259 if ( ! $self->{FILTERS} ) {
260 $self->{FBUFS} = undef;
263 @{$self->{FBUFS}} = map {
266 } ( @{$self->{FILTERS}}, '' );
268 $self->{FBUFS}->[0] = $self->{DEST}
269 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR';
270 push @{$self->{FBUFS}}, $self->{SOURCE};
279 If a filename was passed in, opens it. Determines if the handle is open
280 via fileno(). Throws an exception on error.
287 '<' => O_WRONLY | O_CREAT | O_TRUNC,
288 '<<' => O_WRONLY | O_CREAT | O_APPEND,
292 my IPC::Run::IO $self = shift;
294 croak "IPC::Run::IO: Can't open() a file with no name"
295 unless defined $self->{FILENAME};
296 $self->{HANDLE} = gensym unless $self->{HANDLE};
299 "opening '", $self->filename, "' mode '", $self->mode, "'"
304 $open_flags{$self->op},
306 "IPC::Run::IO: $! opening '$self->{FILENAME}', mode '" . $self->mode . "'";
314 If this is a redirection IO object, this opens the pipe in a platform
321 my ( $child_debug_fd, $parent_handle ) = @_;
324 if ( $self->dir eq "<" ) {
325 ( $self->{TFD}, $self->{FD} ) = IPC::Run::_pipe_nb;
326 if ( $parent_handle ) {
327 CORE::open $parent_handle, ">&=$self->{FD}"
328 or croak "$! duping write end of pipe for caller";
332 ( $self->{FD}, $self->{TFD} ) = IPC::Run::_pipe;
333 if ( $parent_handle ) {
334 CORE::open $parent_handle, "<&=$self->{FD}"
335 or croak "$! duping read end of pipe for caller";
341 my IPC::Run::IO $self = shift;
343 ## Hmmm, Maybe allow named pipes one day. But until then...
344 croak "IPC::Run::IO: Can't pipe() when a file name has been set"
345 if defined $self->{FILENAME};
347 $self->_do_open( @_ );
349 ## return ( child_fd, parent_fd )
350 return $self->dir eq "<"
351 ? ( $self->{TFD}, $self->{FD} )
352 : ( $self->{FD}, $self->{TFD} );
356 sub _cleanup { ## Called from Run.pm's _cleanup
358 undef $self->{FAKE_PIPE};
364 Closes the handle. Throws an exception on failure.
370 my IPC::Run::IO $self = shift;
372 if ( defined $self->{HANDLE} ) {
373 close $self->{HANDLE}
374 or croak( "IPC::Run::IO: $! closing "
375 . ( defined $self->{FILENAME}
376 ? "'$self->{FILENAME}'"
382 IPC::Run::_close( $self->{FD} );
392 Returns the fileno of the handle. Throws an exception on failure.
398 my IPC::Run::IO $self = shift;
400 my $fd = fileno $self->{HANDLE};
401 croak( "IPC::Run::IO: $! "
402 . ( defined $self->{FILENAME}
403 ? "'$self->{FILENAME}'"
406 ) unless defined $fd;
415 Returns the operator in terms of 'r', 'w', and 'a'. There is a state
416 'ra', unlike Perl's open(), which indicates that data read from the
417 handle or file will be appended to the output if the output is a scalar.
418 This is only meaningful if the output is a scalar, it has no effect if
419 the output is a subroutine.
421 The redirection operators can be a little confusing, so here's a reference
424 > r Read from handle in to process
425 < w Write from process out to handle
426 >> ra Read from handle in to process, appending it to existing
427 data if the destination is a scalar.
428 << wa Write from process out to handle, appending to existing
429 data if IPC::Run::IO opened a named file.
434 my IPC::Run::IO $self = shift;
436 croak "IPC::Run::IO: unexpected arguments for mode(): @_" if @_;
438 ## TODO: Optimize this
439 return ( $self->{TYPE} =~ /</ ? 'w' : 'r' ) .
440 ( $self->{TYPE} =~ /<<|>>/ ? 'a' : '' );
446 Returns the operation: '<', '>', '<<', '>>'. See L</mode> if you want
447 to spell these 'r', 'w', etc.
452 my IPC::Run::IO $self = shift;
454 croak "IPC::Run::IO: unexpected arguments for op(): @_" if @_;
456 return $self->{TYPE};
461 Sets/gets whether this pipe is in binmode or not. No effect off of Win32
462 OSs, of course, and on Win32, no effect after the harness is start()ed.
467 my IPC::Run::IO $self = shift;
469 $self->{BINMODE} = shift if @_;
471 return $self->{BINMODE};
477 Returns the first character of $self->op. This is either "<" or ">".
482 my IPC::Run::IO $self = shift;
484 croak "IPC::Run::IO: unexpected arguments for dir(): @_" if @_;
486 return substr $self->{TYPE}, 0, 1;
491 ## Filter Scaffolding
493 #my $filter_op ; ## The op running a filter chain right now
494 #my $filter_num; ## Which filter is being run right now.
497 '$filter_op', ## The op running a filter chain right now
498 '$filter_num' ## Which filter is being run right now.
502 my IPC::Run::IO $self = shift;
504 confess "\$self not an IPC::Run::IO" unless UNIVERSAL::isa( $self, "IPC::Run::IO" );
507 $self->{FBUFS}->[0] = $self->{DEST}
508 if $self->{DEST} && ref $self->{DEST} eq 'SCALAR';
510 return unless $self->{FILTERS} && @{$self->{FILTERS}};
512 push @{$self->{FBUFS}}, map {
515 } ( @{$self->{FILTERS}}, '' );
517 push @{$self->{FBUFS}}, $self->{SOURCE};
522 my IPC::Run::IO $self = shift;
523 my ( $harness ) = @_;
525 if ( defined $self->{FD} ) {
528 if ( vec $harness->{WOUT}, $self->{FD}, 1 ) {
529 _debug_desc_fd( "filtering data to", $self )
530 if _debugging_details;
531 return $self->_do_filters( $harness );
534 elsif ( $d eq ">" ) {
535 if ( vec $harness->{ROUT}, $self->{FD}, 1 ) {
536 _debug_desc_fd( "filtering data from", $self )
537 if _debugging_details;
538 return $self->_do_filters( $harness );
547 my IPC::Run::IO $self = shift;
549 ( $self->{HARNESS} ) = @_;
551 my ( $saved_op, $saved_num ) =($IPC::Run::filter_op,$IPC::Run::filter_num);
552 $IPC::Run::filter_op = $self;
553 $IPC::Run::filter_num = -1;
558 $r = eval { IPC::Run::get_more_input(); };
560 ##$@ and warn "redo ", substr($@, 0, 20) , " ";
561 (($c < 200) and ($@||'')=~ m/^Resource temporarily/) and redo;
563 ( $IPC::Run::filter_op, $IPC::Run::filter_num ) = ( $saved_op, $saved_num );
564 $self->{HARNESS} = undef;
565 die "ack ", $@ if $@;