7 IPC::Run3 - Run a subprocess in batch mode (a la system) on Unix, Win32, etc.
11 use IPC::Run3; ## Exports run3() by default
12 use IPC::Run3 (); ## Don't pollute
14 run3 \@cmd, \$in, \$out, \$err;
15 run3 \@cmd, \@in, \&out, \$err;
19 This module allows you to run a subprocess and redirect stdin, stdout,
20 and/or stderr to files and perl data structures. It aims to satisfy 99%
21 of the need for using system()/qx``/open3() with a simple, extremely
22 Perlish API and none of the bloat and rarely used features of IPC::Run.
24 Speed (of Perl code; which is often much slower than the kind of
25 buffered I/O that this module uses to spool input to and output from the
26 child command), simplicity, and portability are paramount. Disk space
29 Note that passing in \undef explicitly redirects the associated file
30 descriptor for STDIN, STDOUT, or STDERR from or to the local equivalent
31 of /dev/null (this does I<not> pass a closed filehandle). Passing in
32 "undef" (or not passing a redirection) allows the child to inherit the
33 corresponding STDIN, STDOUT, or STDERR from the parent.
35 Because the redirects come last, this allows STDOUT and STDERR to
36 default to the parent's by just not specifying them; a common use
39 B<Note>: This means that:
41 run3 \@cmd, undef, \$out; ## Pass on parent's STDIN
43 B<does not close the child's STDIN>, it passes on the parent's. Use
45 run3 \@cmd, \undef, \$out; ## Close child's STDIN
47 for that. It's not ideal, but it does work.
49 If the exact same value is passed for $stdout and $stderr, then
50 the child will write both to the same filehandle. In general, this
53 run3 \@cmd, \undef, "foo.txt", "foo.txt";
54 run3 \@cmd, \undef, \$both, \$both;
56 will DWYM and pass a single file handle to the child for both
57 STDOUT and STDERR, collecting all into $both.
61 To enable debugging use the IPCRUN3DEBUG environment variable to
62 a non-zero integer value:
64 $ IPCRUN3DEBUG=1 myapp
70 To enable profiling, set IPCRUN3PROFILE to a number to enable
71 emitting profile information to STDERR (1 to get timestamps,
72 2 to get a summary report at the END of the program,
73 3 to get mini reports after each run) or to a filename to
74 emit raw data to a file for later analysis.
78 Here's how it stacks up to existing APIs:
82 =item compared to system(), qx'', open "...|", open "|...":
86 =item + redirects more than one file descriptor
88 =item + returns TRUE on success, FALSE on failure
90 =item + throws an error if problems occur in the parent process (or the
93 =item + allows a very perlish interface to perl data structures and
96 =item + allows 1 word invocations to avoid the shell easily:
98 run3 ["foo"]; ## does not invoke shell
100 =item - does not return the exit code, leaves it in $?
104 =item compared to open2(), open3():
108 =item + No lengthy, error prone polling / select loop needed
110 =item + Hides OS dependancies
112 =item + Allows SCALAR, ARRAY, and CODE references to source and sink I/O
114 =item + I/O parameter order is like open3() (not like open2()).
116 =item - Does not allow interaction with the subprocess
120 =item compared to IPC::Run::run():
124 =item + Smaller, lower overhead, simpler, more portable
126 =item + No select() loop portability issues
128 =item + Does not fall prey to Perl closure leaks
130 =item - Does not allow interaction with the subprocess (which
131 IPC::Run::run() allows by redirecting subroutines).
133 =item - Lacks many features of IPC::Run::run() (filters, pipes,
134 redirects, pty support).
142 @EXPORT = qw( run3 );
143 %EXPORT_TAGS = ( all
=> \
@EXPORT );
144 @ISA = qw( Exporter );
148 use constant debugging
=> $ENV{IPCRUN3DEBUG
} || $ENV{IPCRUNDEBUG
} || 0;
149 use constant profiling
=> $ENV{IPCRUN3PROFILE
} || $ENV{IPCRUNPROFILE
} || 0;
150 use constant is_win32
=> 0 <= index $^O, "Win32";
154 eval "use Win32 qw( GetOSName ); 1" or die $@;
158 #use constant is_win2k => is_win32 && GetOSName() =~ /Win2000/i;
159 #use constant is_winXP => is_win32 && GetOSName() =~ /WinXP/i;
161 use Carp qw( croak );
162 use File
::Temp
qw( tempfile );
163 use UNIVERSAL
qw( isa );
164 use POSIX
qw( dup dup2 );
166 ## We cache the handles of our temp files in order to
167 ## keep from having to incur the (largish) overhead of File::Temp
172 sub _profiler
{ $profiler } ## test suite access
176 eval "use Time::HiRes qw( gettimeofday ); 1" or die $@;
177 if ( $ENV{IPCRUN3PROFILE} =~ /\A\d+\z/ ) {
178 require IPC::Run3::ProfPP;
179 $profiler = IPC::Run3::ProfPP->new(
180 Level => $ENV{IPCRUN3PROFILE},
184 my ( $dest, undef, $class ) =
185 reverse split /(=)/, $ENV{IPCRUN3PROFILE}, 2;
186 $class = "IPC
::Run3
::ProfLogger
"
187 unless defined $class && length $class;
188 unless ( eval "require $class" ) {
190 $class = "IPC
::Run3
::$class";
191 eval "require IPC
::Run3
::$class" or die $x;
193 $profiler = $class->new(
194 Destination => $dest,
197 $profiler->app_call( [ $0, @ARGV ], scalar gettimeofday() );
203 $profiler->app_exit( scalar gettimeofday() ) if profiling;
207 sub _spool_data_to_child {
208 my ( $type, $source, $binmode_it ) = @_;
210 ## If undef (not \undef) passed, they want the child to inherit
211 ## the parent's STDIN.
212 return undef unless defined $source;
213 warn "binmode()ing STDIN
\n" if is_win32 && debugging && $binmode_it;
217 local *FH; ## Do this the backcompat way
218 open FH, "<$source" or croak "$!: $source";
221 binmode ":raw
"; ## Remove all layers
222 binmode ":crlf
" unless $binmode_it;
224 warn "run3
(): feeding file
'$source' to child STDIN
\n"
227 elsif ( $type eq "FH
" ) {
229 warn "run3
(): feeding filehandle
'$source' to child STDIN
\n"
233 $fh = $fh_cache{in} ||= tempfile;
237 binmode $fh, ":raw
"; ## Remove any previous layers
238 binmode $fh, ":crlf
" unless $binmode_it;
241 if ( $type eq "SCALAR
" ) {
243 ## When the run3()'s caller asks to feed an empty file
244 ## to the child's stdin, we want to pass a live file
245 ## descriptor to an empty file (like /dev/null) so that
246 ## they don't get surprised by invalid fd errors and get
247 ## normal EOF behaviors.
248 return $fh unless defined $$source; ## \undef passed
250 warn "run3
(): feeding SCALAR to child STDIN
",
252 ? ( ": '", $$source, "' (", length $$source, " chars
)" )
257 $seekit = length $$source;
258 print $fh $$source or die "$! writing to temp file
";
261 elsif ( $type eq "ARRAY
" ) {
262 warn "run3
(): feeding ARRAY to child STDIN
",
263 debugging >= 3 ? ( ": '", @$source, "'" ) : (),
267 print $fh @$source or die "$! writing to temp file
";
268 $seekit = grep length, @$source;
270 elsif ( $type eq "CODE
" ) {
271 warn "run3
(): feeding output of CODE
ref '$source' to child STDIN
\n"
273 my $parms = []; ## TODO: get these from $options
275 my $data = $source->( @$parms );
276 last unless defined $data;
277 print $fh $data or die "$! writing to temp file
";
278 $seekit = length $data;
282 seek $fh, 0, 0 or croak "$! seeking on temp file
for child
's stdin"
286 croak "run3() can't redirect
$type to child stdin
"
293 sub _fh_for_child_output {
294 my ( $what, $type, $dest, $binmode_it ) = @_;
297 if ( $type eq "SCALAR
" && $dest == \undef ) {
298 warn "run3
(): redirecting child
$what to oblivion
\n"
301 $fh = $fh_cache{nul} ||= do {
303 open FH, ">" . File::Spec->devnull;
308 warn "run3
(): feeding child
$what to file
'$dest'\n"
312 open FH, ">$dest" or croak "$!: $dest";
316 warn "run3
(): capturing child
$what\n"
319 $fh = $fh_cache{$what} ||= tempfile;
325 warn "binmode()ing
$what\n" if debugging && $binmode_it;
327 binmode $fh, ":crlf
" unless $binmode_it;
333 sub _read_child_output_fh {
334 my ( $what, $type, $dest, $fh, $options ) = @_;
336 return if $type eq "SCALAR
" && $dest == \undef;
338 seek $fh, 0, 0 or croak "$! seeking on temp file
for child
$what";
340 if ( $type eq "SCALAR
" ) {
341 warn "run3
(): reading child
$what to SCALAR
\n"
344 ## two read()s are used instead of 1 so that the first will be
345 ## logged even it reads 0 bytes; the second won't.
346 my $count = read $fh, $$dest, 10_000;
348 croak "$! reading child
$what from temp file
"
349 unless defined $count;
353 warn "run3
(): read $count bytes from child
$what",
354 debugging >= 3 ? ( ": '", substr( $$dest, -$count ), "'" ) : (),
358 $count = read $fh, $$dest, 10_000, length $$dest;
361 elsif ( $type eq "ARRAY
" ) {
363 if ( debugging >= 2 ) {
365 $count += length for @$dest;
369 " records
, $count bytes from child
$what",
370 debugging >= 3 ? ( ": '", @$dest, "'" ) : (),
374 elsif ( $type eq "CODE
" ) {
375 warn "run3
(): capturing child
$what to CODE
ref\n"
383 " bytes from child
$what",
384 debugging >= 3 ? ( ": '", $_, "'" ) : (),
392 croak "run3
() can
't redirect child $what to a $type";
401 return "FH" if isa $redir, "IO::Handle";
402 my $type = ref $redir;
403 return $type eq "GLOB" ? "FH" : $type;
418 $run_call_time = gettimeofday() if profiling;
420 my $options = @_ && ref $_[-1] eq "HASH" ? pop : {};
422 my ( $cmd, $stdin, $stdout, $stderr ) = @_;
424 print STDERR "run3(): running ",
425 join( " ", map "'$_'", ref $cmd ? @$cmd : $cmd ),
430 croak "run3(): empty command" unless @$cmd;
431 croak "run3(): undefined command" unless defined $cmd->[0];
432 croak "run3(): command name ('')" unless length $cmd->[0];
435 croak "run3(): missing command" unless @_;
436 croak "run3(): undefined command" unless defined $cmd;
437 croak "run3(): command ('')" unless length $cmd;
440 my $in_type = _type $stdin;
441 my $out_type = _type $stdout;
442 my $err_type = _type $stderr;
444 ## This routine procedes in stages so that a failure in an early
445 ## stage prevents later stages from running, and thus from needing
448 my $in_fh = _spool_data_to_child $in_type, $stdin,
449 $options->{binmode_stdin} if defined $stdin;
451 my $out_fh = _fh_for_child_output "stdout", $out_type, $stdout,
452 $options->{binmode_stdout} if defined $stdout;
455 defined $stderr && defined $stdout && $stderr eq $stdout;
457 my $err_fh = $tie_err_to_out
459 : _fh_for_child_output "stderr", $err_type, $stderr,
460 $options->{binmode_stderr} if defined $stderr;
462 ## this should make perl close these on exceptions
467 my $saved_fd0 = dup( 0 ) if defined $in_fh;
469 # open STDIN_SAVE, "<&STDIN"# or croak "run3(): $! saving STDIN"
471 open STDOUT_SAVE, ">&STDOUT" or croak "run3(): $! saving STDOUT"
473 open STDERR_SAVE, ">&STDERR" or croak "run3(): $! saving STDERR"
477 ## The open() call here seems to not force fd 0 in some cases;
478 ## I ran in to trouble when using this in VCP, not sure why.
479 ## the dup2() seems to work.
480 dup2( fileno $in_fh, 0 )
481 # open STDIN, "<&=" . fileno $in_fh
482 or croak "run3(): $! redirecting STDIN"
485 # close $in_fh or croak "$! closing STDIN temp file"
488 open STDOUT, ">&" . fileno $out_fh
489 or croak "run3(): $! redirecting STDOUT"
492 open STDERR, ">&" . fileno $err_fh
493 or croak "run3(): $! redirecting STDERR"
496 $sys_call_time = gettimeofday() if profiling;
502 ## Probably need to offer a win32 escaping
503 ## option, every command may be different.
504 ( my $s = $_ ) =~ s/"/"""/g;
511 $sys_exit_time = gettimeofday
() if profiling
;
513 unless ( defined $r ) {
515 my $err_fh = defined $err_fh ? \
*STDERR_SAVE
: \
*STDERR
;
516 print $err_fh "run3(): system() error $!\n"
522 my $err_fh = defined $err_fh ? \
*STDERR_SAVE
: \
*STDERR
;
523 print $err_fh "run3(): \$? is $?\n"
531 if ( defined $saved_fd0 ) {
532 dup2
( $saved_fd0, 0 );
533 POSIX
::close( $saved_fd0 );
536 # open STDIN, "<&STDIN_SAVE"# or push @errs, "run3(): $! restoring STDIN"
538 open STDOUT
, ">&STDOUT_SAVE" or push @errs, "run3(): $! restoring STDOUT"
540 open STDERR
, ">&STDERR_SAVE" or push @errs, "run3(): $! restoring STDERR"
543 croak
join ", ", @errs if @errs;
547 _read_child_output_fh
"stdout", $out_type, $stdout, $out_fh, $options
548 if defined $out_fh && $out_type && $out_type ne "FH";
549 _read_child_output_fh
"stderr", $err_type, $stderr, $err_fh, $options
550 if defined $err_fh && $err_type && $err_type ne "FH" && !$tie_err_to_out;
569 $in_fd = fileno $in_fh;
571 $out_fd = fileno $out_fh;
573 $err_fd = fileno $err_fh;
574 my $saved_fd0 = dup
0;
575 my $saved_fd1 = dup
1;
576 my $saved_fd2 = dup
2;
578 my ( $cmd, $stdin, $stdout, $stderr );
581 ( $cmd, $stdin, $stdout, $stderr ) = @_;
586 print $in_fh $$stdin or die "$! writing to temp file";
595 dup2
$in_fd, 0 or croak
"run3(): $! redirecting STDIN";
596 dup2
$out_fd, 1 or croak
"run3(): $! redirecting STDOUT";
597 dup2
$err_fd, 2 or croak
"run3(): $! redirecting STDERR";
603 ## Probably need to offer a win32 escaping
604 ## option, every command is different.
605 ( my $s = $_ ) =~ s/"/"""/g;
606 $s = q{"$s"} if /[^\w.:\/\\'-]/;
611 die $! unless defined $r;
617 seek $out_fh, 0, 0 or croak "$! seeking on temp file for child output";
619 my $count = read $out_fh, $$stdout, 10_000;
620 while ( $count == 10_000 ) {
621 $count = read $out_fh, $$stdout, 10_000, length $$stdout;
623 croak "$! reading child output from temp file"
624 unless defined $count;
626 seek $err_fh, 0, 0 or croak "$! seeking on temp file for child errput";
628 $count = read $err_fh, $$stderr, 10_000;
629 while ( $count == 10_000 ) {
630 $count = read $err_fh, $$stderr, 10_000, length $$stdout;
632 croak "$! reading child stderr from temp file"
633 unless defined $count;
647 Often uses intermediate files (determined by File::Temp, and thus by the
648 File::Spec defaults and the TMPDIR env. variable) for speed, portability and
653 Copyright 2003, R. Barrie Slaymaker, Jr., All Rights Reserved
657 You may use this module under the terms of the BSD, Artistic, or GPL licenses,
662 Barrie Slaymaker <barries@slaysys.com>