]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/regressions/t/IPC/Run3.pm
Security-57740.51.3.tar.gz
[apple/security.git] / SecurityTests / regressions / t / IPC / Run3.pm
diff --git a/SecurityTests/regressions/t/IPC/Run3.pm b/SecurityTests/regressions/t/IPC/Run3.pm
deleted file mode 100644 (file)
index c011d97..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-package IPC::Run3;
-
-$VERSION = 0.010;
-
-=head1 NAME
-
-IPC::Run3 - Run a subprocess in batch mode (a la system) on Unix, Win32, etc.
-
-=head1 SYNOPSIS
-
-    use IPC::Run3;    ## Exports run3() by default
-    use IPC::Run3 (); ## Don't pollute
-
-    run3 \@cmd, \$in, \$out, \$err;
-    run3 \@cmd, \@in, \&out, \$err;
-
-=head1 DESCRIPTION
-
-This module allows you to run a subprocess and redirect stdin, stdout,
-and/or stderr to files and perl data structures.  It aims to satisfy 99%
-of the need for using system()/qx``/open3() with a simple, extremely
-Perlish API and none of the bloat and rarely used features of IPC::Run.
-
-Speed (of Perl code; which is often much slower than the kind of
-buffered I/O that this module uses to spool input to and output from the
-child command), simplicity, and portability are paramount.  Disk space
-is not.
-
-Note that passing in \undef explicitly redirects the associated file
-descriptor for STDIN, STDOUT, or STDERR from or to the local equivalent
-of /dev/null (this does I<not> pass a closed filehandle).  Passing in
-"undef" (or not passing a redirection) allows the child to inherit the
-corresponding STDIN, STDOUT, or STDERR from the parent.
-
-Because the redirects come last, this allows STDOUT and STDERR to
-default to the parent's by just not specifying them; a common use
-case.
-
-B<Note>: This means that:
-
-    run3 \@cmd, undef, \$out;   ## Pass on parent's STDIN
-
-B<does not close the child's STDIN>, it passes on the parent's.  Use
-
-    run3 \@cmd, \undef, \$out;  ## Close child's STDIN
-
-for that.  It's not ideal, but it does work.
-
-If the exact same value is passed for $stdout and $stderr, then
-the child will write both to the same filehandle.  In general, this
-means that
-
-    run3 \@cmd, \undef, "foo.txt", "foo.txt";
-    run3 \@cmd, \undef, \$both, \$both;
-
-will DWYM and pass a single file handle to the child for both
-STDOUT and STDERR, collecting all into $both.
-
-=head1 DEBUGGING
-
-To enable debugging use the IPCRUN3DEBUG environment variable to
-a non-zero integer value:
-
-    $ IPCRUN3DEBUG=1 myapp
-
-.
-
-=head1 PROFILING
-
-To enable profiling, set IPCRUN3PROFILE to a number to enable
-emitting profile information to STDERR (1 to get timestamps,
-2 to get a summary report at the END of the program,
-3 to get mini reports after each run) or to a filename to
-emit raw data to a file for later analysis.
-
-=head1 COMPARISON
-
-Here's how it stacks up to existing APIs:
-
-=over
-
-=item compared to system(), qx'', open "...|", open "|...":
-
-=over
-
-=item + redirects more than one file descriptor
-
-=item + returns TRUE on success, FALSE on failure
-
-=item + throws an error if problems occur in the parent process (or the
-pre-exec child)
-
-=item + allows a very perlish interface to perl data structures and
-subroutines
-
-=item + allows 1 word invocations to avoid the shell easily:
-
-    run3 ["foo"];  ## does not invoke shell
-
-=item - does not return the exit code, leaves it in $?
-
-=back
-
-=item compared to open2(), open3():
-
-=over
-
-=item + No lengthy, error prone polling / select loop needed
-
-=item + Hides OS dependancies
-
-=item + Allows SCALAR, ARRAY, and CODE references to source and sink I/O
-
-=item + I/O parameter order is like open3()  (not like open2()).
-
-=item - Does not allow interaction with the subprocess
-
-=back
-
-=item compared to IPC::Run::run():
-
-=over
-
-=item + Smaller, lower overhead, simpler, more portable
-
-=item + No select() loop portability issues
-
-=item + Does not fall prey to Perl closure leaks
-
-=item - Does not allow interaction with the subprocess (which
-IPC::Run::run() allows by redirecting subroutines).
-
-=item - Lacks many features of IPC::Run::run() (filters, pipes,
-redirects, pty support).
-
-=back
-
-=back
-
-=cut
-
-@EXPORT = qw( run3 );
-%EXPORT_TAGS = ( all => \@EXPORT );
-@ISA = qw( Exporter );
-use Exporter;
-
-use strict;
-use constant debugging => $ENV{IPCRUN3DEBUG} || $ENV{IPCRUNDEBUG} || 0;
-use constant profiling => $ENV{IPCRUN3PROFILE} || $ENV{IPCRUNPROFILE} || 0;
-use constant is_win32  => 0 <= index $^O, "Win32";
-
-BEGIN {
-   if ( is_win32 ) {
-      eval "use Win32 qw( GetOSName ); 1" or die $@;
-   }
-}
-
-#use constant is_win2k => is_win32 && GetOSName() =~ /Win2000/i;
-#use constant is_winXP => is_win32 && GetOSName() =~ /WinXP/i;
-
-use Carp qw( croak );
-use File::Temp qw( tempfile );
-use UNIVERSAL qw( isa );
-use POSIX qw( dup dup2 );
-
-## We cache the handles of our temp files in order to
-## keep from having to incur the (largish) overhead of File::Temp
-my %fh_cache;
-
-my $profiler;
-
-sub _profiler { $profiler } ## test suite access
-
-BEGIN {
-    if ( profiling ) {
-        eval "use Time::HiRes qw( gettimeofday ); 1" or die $@;
-        if ( $ENV{IPCRUN3PROFILE} =~ /\A\d+\z/ ) {
-            require IPC::Run3::ProfPP;
-            $profiler = IPC::Run3::ProfPP->new(
-                Level => $ENV{IPCRUN3PROFILE},
-            );
-        }
-        else {
-            my ( $dest, undef, $class ) =
-               reverse split /(=)/, $ENV{IPCRUN3PROFILE}, 2;
-            $class = "IPC::Run3::ProfLogger"
-                unless defined $class && length $class;
-            unless ( eval "require $class" ) {
-                my $x = $@;
-                $class = "IPC::Run3::$class";
-                eval "require IPC::Run3::$class" or die $x;
-            }
-            $profiler = $class->new(
-                Destination => $dest,
-            );
-        }
-        $profiler->app_call( [ $0, @ARGV ], scalar gettimeofday() );
-    }
-}
-
-
-END {
-    $profiler->app_exit( scalar gettimeofday() ) if profiling;
-}
-
-
-sub _spool_data_to_child {
-    my ( $type, $source, $binmode_it ) = @_;
-
-    ## If undef (not \undef) passed, they want the child to inherit
-    ## the parent's STDIN.
-    return undef unless defined $source;
-    warn "binmode()ing STDIN\n" if is_win32 && debugging && $binmode_it;
-
-    my $fh;
-    if ( ! $type ) {
-        local *FH;  ## Do this the backcompat way
-        open FH, "<$source" or croak "$!: $source";
-        $fh = *FH{IO};
-        if ( is_win32 ) {
-            binmode ":raw"; ## Remove all layers
-            binmode ":crlf" unless $binmode_it;
-        }
-        warn "run3(): feeding file '$source' to child STDIN\n"
-            if debugging >= 2;
-    }
-    elsif ( $type eq "FH" ) {
-        $fh = $source;
-        warn "run3(): feeding filehandle '$source' to child STDIN\n"
-            if debugging >= 2;
-    }
-    else {
-        $fh = $fh_cache{in} ||= tempfile;
-        truncate $fh, 0;
-        seek $fh, 0, 0;
-        if ( is_win32 ) {
-            binmode $fh, ":raw"; ## Remove any previous layers
-            binmode $fh, ":crlf" unless $binmode_it;
-        }
-        my $seekit;
-        if ( $type eq "SCALAR" ) {
-
-            ## When the run3()'s caller asks to feed an empty file
-            ## to the child's stdin, we want to pass a live file
-            ## descriptor to an empty file (like /dev/null) so that
-            ## they don't get surprised by invalid fd errors and get
-            ## normal EOF behaviors.
-            return $fh unless defined $$source;  ## \undef passed
-
-            warn "run3(): feeding SCALAR to child STDIN",
-                debugging >= 3
-                   ? ( ": '", $$source, "' (", length $$source, " chars)" )
-                   : (),
-                "\n"
-                if debugging >= 2;
-
-            $seekit = length $$source;
-            print $fh $$source or die "$! writing to temp file";
-
-        }
-        elsif ( $type eq "ARRAY" ) {
-            warn "run3(): feeding ARRAY to child STDIN",
-                debugging >= 3 ? ( ": '", @$source, "'" ) : (),
-                "\n"
-            if debugging >= 2;
-
-            print $fh @$source or die "$! writing to temp file";
-            $seekit = grep length, @$source;
-        }
-        elsif ( $type eq "CODE" ) {
-            warn "run3(): feeding output of CODE ref '$source' to child STDIN\n"
-                if debugging >= 2;
-            my $parms = [];  ## TODO: get these from $options
-            while (1) {
-                my $data = $source->( @$parms );
-                last unless defined $data;
-                print $fh $data or die "$! writing to temp file";
-                $seekit = length $data;
-            }
-        }
-
-        seek $fh, 0, 0 or croak "$! seeking on temp file for child's stdin"
-            if $seekit;
-    }
-
-    croak "run3() can't redirect $type to child stdin"
-        unless defined $fh;
-
-    return $fh;
-}
-
-
-sub _fh_for_child_output {
-    my ( $what, $type, $dest, $binmode_it ) = @_;
-
-    my $fh;
-    if ( $type eq "SCALAR" && $dest == \undef ) {
-        warn "run3(): redirecting child $what to oblivion\n"
-            if debugging >= 2;
-
-        $fh = $fh_cache{nul} ||= do {
-            local *FH;
-            open FH, ">" . File::Spec->devnull;
-            *FH{IO};
-        };
-    }
-    elsif ( !$type ) {
-        warn "run3(): feeding child $what to file '$dest'\n"
-            if debugging >= 2;
-
-        local *FH;
-        open FH, ">$dest" or croak "$!: $dest";
-        $fh = *FH{IO};
-    }
-    else {
-        warn "run3(): capturing child $what\n"
-            if debugging >= 2;
-
-        $fh = $fh_cache{$what} ||= tempfile;
-        seek $fh, 0, 0;
-        truncate $fh, 0;
-    }
-
-    if ( is_win32 ) {
-        warn "binmode()ing $what\n" if debugging && $binmode_it;
-        binmode $fh, ":raw";
-        binmode $fh, ":crlf" unless $binmode_it;
-    }
-    return $fh;
-}
-
-
-sub _read_child_output_fh {
-    my ( $what, $type, $dest, $fh, $options ) = @_;
-
-    return if $type eq "SCALAR" && $dest == \undef;
-
-    seek $fh, 0, 0 or croak "$! seeking on temp file for child $what";
-
-    if ( $type eq "SCALAR" ) {
-        warn "run3(): reading child $what to SCALAR\n"
-            if debugging >= 3;
-
-        ## two read()s are used instead of 1 so that the first will be
-        ## logged even it reads 0 bytes; the second won't.
-        my $count = read $fh, $$dest, 10_000;
-        while (1) {
-            croak "$! reading child $what from temp file"
-                unless defined $count;
-
-            last unless $count;
-
-            warn "run3(): read $count bytes from child $what",
-                debugging >= 3 ? ( ": '", substr( $$dest, -$count ), "'" ) : (),
-                "\n"
-                if debugging >= 2;
-
-            $count = read $fh, $$dest, 10_000, length $$dest;
-        }
-    }
-    elsif ( $type eq "ARRAY" ) {
-        @$dest = <$fh>;
-        if ( debugging >= 2 ) {
-            my $count = 0;
-            $count += length for @$dest;
-            warn
-                "run3(): read ",
-                scalar @$dest,
-                " records, $count bytes from child $what",
-                debugging >= 3 ? ( ": '", @$dest, "'" ) : (),
-                "\n";
-        }
-    }
-    elsif ( $type eq "CODE" ) {
-        warn "run3(): capturing child $what to CODE ref\n"
-            if debugging >= 3;
-
-        local $_;
-        while ( <$fh> ) {
-            warn
-                "run3(): read ",
-                length,
-                " bytes from child $what",
-                debugging >= 3 ? ( ": '", $_, "'" ) : (),
-                "\n"
-                if debugging >= 2;
-
-            $dest->( $_ );
-        }
-    }
-    else {
-        croak "run3() can't redirect child $what to a $type";
-    }
-
-#    close $fh;
-}
-
-
-sub _type {
-    my ( $redir ) = @_;
-    return "FH" if isa $redir, "IO::Handle";
-    my $type = ref $redir;
-    return $type eq "GLOB" ? "FH" : $type;
-}
-
-
-sub _max_fd {
-    my $fd = dup(0);
-    POSIX::close $fd;
-    return $fd;
-}
-
-my $run_call_time;
-my $sys_call_time;
-my $sys_exit_time;
-
-sub run3 {
-    $run_call_time = gettimeofday() if profiling;
-
-    my $options = @_ && ref $_[-1] eq "HASH" ? pop : {};
-
-    my ( $cmd, $stdin, $stdout, $stderr ) = @_;
-
-    print STDERR "run3(): running ", 
-       join( " ", map "'$_'", ref $cmd ? @$cmd : $cmd ), 
-       "\n"
-       if debugging;
-
-    if ( ref $cmd ) {
-        croak "run3(): empty command"     unless @$cmd;
-        croak "run3(): undefined command" unless defined $cmd->[0];
-        croak "run3(): command name ('')" unless length  $cmd->[0];
-    }
-    else {
-        croak "run3(): missing command" unless @_;
-        croak "run3(): undefined command" unless defined $cmd;
-        croak "run3(): command ('')" unless length  $cmd;
-    }
-
-    my $in_type  = _type $stdin;
-    my $out_type = _type $stdout;
-    my $err_type = _type $stderr;
-
-    ## This routine procedes in stages so that a failure in an early
-    ## stage prevents later stages from running, and thus from needing
-    ## cleanup.
-
-    my $in_fh  = _spool_data_to_child $in_type, $stdin,
-        $options->{binmode_stdin} if defined $stdin;
-
-    my $out_fh = _fh_for_child_output "stdout", $out_type, $stdout,
-        $options->{binmode_stdout} if defined $stdout;
-
-    my $tie_err_to_out =
-        defined $stderr && defined $stdout && $stderr eq $stdout;
-
-    my $err_fh = $tie_err_to_out
-        ? $out_fh
-        : _fh_for_child_output "stderr", $err_type, $stderr,
-            $options->{binmode_stderr} if defined $stderr;
-
-    ## this should make perl close these on exceptions
-    local *STDIN_SAVE;
-    local *STDOUT_SAVE;
-    local *STDERR_SAVE;
-
-    my $saved_fd0 = dup( 0 ) if defined $in_fh;
-
-#    open STDIN_SAVE,  "<&STDIN"#  or croak "run3(): $! saving STDIN"
-#        if defined $in_fh;
-    open STDOUT_SAVE, ">&STDOUT" or croak "run3(): $! saving STDOUT"
-        if defined $out_fh;
-    open STDERR_SAVE, ">&STDERR" or croak "run3(): $! saving STDERR"
-        if defined $err_fh;
-
-    my $ok = eval {
-        ## The open() call here seems to not force fd 0 in some cases;
-        ## I ran in to trouble when using this in VCP, not sure why.
-        ## the dup2() seems to work.
-        dup2( fileno $in_fh, 0 )
-#        open STDIN,  "<&=" . fileno $in_fh
-            or croak "run3(): $! redirecting STDIN"
-            if defined $in_fh;
-
-#        close $in_fh or croak "$! closing STDIN temp file"
-#            if ref $stdin;
-
-        open STDOUT, ">&" . fileno $out_fh
-            or croak "run3(): $! redirecting STDOUT"
-            if defined $out_fh;
-
-        open STDERR, ">&" . fileno $err_fh
-            or croak "run3(): $! redirecting STDERR"
-            if defined $err_fh;
-
-        $sys_call_time = gettimeofday() if profiling;
-
-        my $r = ref $cmd
-           ? system {$cmd->[0]}
-                   is_win32
-                       ? map {
-                           ## Probably need to offer a win32 escaping
-                           ## option, every command may be different.
-                           ( my $s = $_ ) =~ s/"/"""/g;
-                           $s = qq{"$s"};
-                           $s;
-                       } @$cmd
-                       : @$cmd
-           : system $cmd;
-
-        $sys_exit_time = gettimeofday() if profiling;
-
-        unless ( defined $r ) {
-            if ( debugging ) {
-                my $err_fh = defined $err_fh ? \*STDERR_SAVE : \*STDERR;
-                print $err_fh "run3(): system() error $!\n"
-            }
-            die $!;
-        }
-
-        if ( debugging ) {
-            my $err_fh = defined $err_fh ? \*STDERR_SAVE : \*STDERR;
-            print $err_fh "run3(): \$? is $?\n"
-        }
-        1;
-    };
-    my $x = $@;
-
-    my @errs;
-
-    if ( defined $saved_fd0 ) {
-        dup2( $saved_fd0, 0 );
-        POSIX::close( $saved_fd0 );
-    }
-
-#    open STDIN,  "<&STDIN_SAVE"#  or push @errs, "run3(): $! restoring STDIN"
-#        if defined $in_fh;
-    open STDOUT, ">&STDOUT_SAVE" or push @errs, "run3(): $! restoring STDOUT"
-        if defined $out_fh;
-    open STDERR, ">&STDERR_SAVE" or push @errs, "run3(): $! restoring STDERR"
-        if defined $err_fh;
-
-    croak join ", ", @errs if @errs;
-
-    die $x unless $ok;
-
-    _read_child_output_fh "stdout", $out_type, $stdout, $out_fh, $options
-        if defined $out_fh && $out_type && $out_type ne "FH";
-    _read_child_output_fh "stderr", $err_type, $stderr, $err_fh, $options
-        if defined $err_fh && $err_type && $err_type ne "FH" && !$tie_err_to_out;
-    $profiler->run_exit(
-       $cmd,
-       $run_call_time,
-       $sys_call_time,
-       $sys_exit_time,
-       scalar gettimeofday 
-    ) if profiling;
-
-    return 1;
-}
-
-my $in_fh;
-my $in_fd;
-my $out_fh;
-my $out_fd;
-my $err_fh;
-my $err_fd;
-        $in_fh = tempfile;
-        $in_fd = fileno $in_fh;
-        $out_fh = tempfile;
-        $out_fd = fileno $out_fh;
-        $err_fh = tempfile;
-        $err_fd = fileno $err_fh;
-    my $saved_fd0 = dup 0;
-    my $saved_fd1 = dup 1;
-    my $saved_fd2 = dup 2;
-    my $r;
-    my ( $cmd, $stdin, $stdout, $stderr );
-
-sub _run3 {
-    ( $cmd, $stdin, $stdout, $stderr ) = @_;
-
-    truncate $in_fh, 0;
-    seek $in_fh, 0, 0;
-
-    print $in_fh $$stdin or die "$! writing to temp file";
-    seek $in_fh, 0, 0;
-
-    seek $out_fh, 0, 0;
-    truncate $out_fh, 0;
-
-    seek $err_fh, 0, 0;
-    truncate $err_fh, 0;
-
-    dup2 $in_fd,  0 or croak "run3(): $! redirecting STDIN";
-    dup2 $out_fd, 1 or croak "run3(): $! redirecting STDOUT";
-    dup2 $err_fd, 2 or croak "run3(): $! redirecting STDERR";
-
-    $r = 
-       system {$cmd->[0]}
-               is_win32
-                   ? map {
-                       ## Probably need to offer a win32 escaping
-                       ## option, every command is different.
-                       ( my $s = $_ ) =~ s/"/"""/g;
-                       $s = q{"$s"} if /[^\w.:\/\\'-]/;
-                       $s;
-                   } @$cmd
-                   : @$cmd;
-
-    die $! unless defined $r;
-
-    dup2 $saved_fd0, 0;
-    dup2 $saved_fd1, 1;
-    dup2 $saved_fd2, 2;
-
-    seek $out_fh, 0, 0 or croak "$! seeking on temp file for child output";
-
-        my $count = read $out_fh, $$stdout, 10_000;
-        while ( $count == 10_000 ) {
-            $count = read $out_fh, $$stdout, 10_000, length $$stdout;
-        }
-        croak "$! reading child output from temp file"
-            unless defined $count;
-
-    seek $err_fh, 0, 0 or croak "$! seeking on temp file for child errput";
-
-        $count = read $err_fh, $$stderr, 10_000;
-        while ( $count == 10_000 ) {
-            $count = read $err_fh, $$stderr, 10_000, length $$stdout;
-        }
-        croak "$! reading child stderr from temp file"
-            unless defined $count;
-
-    return 1;
-}
-
-=cut
-
-
-=head1 TODO
-
-pty support
-
-=head1 LIMITATIONS
-
-Often uses intermediate files (determined by File::Temp, and thus by the
-File::Spec defaults and the TMPDIR env. variable) for speed, portability and
-simplicity.
-
-=head1 COPYRIGHT
-
-    Copyright 2003, R. Barrie Slaymaker, Jr., All Rights Reserved
-
-=head1 LICENSE
-
-You may use this module under the terms of the BSD, Artistic, or GPL licenses,
-any version.
-
-=head1 AUTHOR
-
-Barrie Slaymaker <barries@slaysys.com>
-
-=cut
-
-1;