IPC-Open3-Callback

 view release on metacpan or  search on metacpan

t/Callback.t  view on Meta::CPAN

$runner->run_command(
    "echo", "Hello", "World",
    {   out_callback => sub {
            $buffer .= shift;
        }
    }
);
like( $buffer, $echo_result_regex, "out_callback as command option" );

( $pid, $in, $out, $err ) = safe_open3("echo $echo");
$buffer = '';
my $select = IO::Select->new();
$select->add($out);
while ( my @ready = $select->can_read(5) ) {
    foreach my $fh (@ready) {
        my $line;
        my $bytes_read = sysread( $fh, $line, 1024 );
        if ( !defined($bytes_read) && !$!{ECONNRESET} ) {
            die("error in running ('echo $echo'): $!");
        }
        elsif ( !defined($bytes_read) || $bytes_read == 0 ) {
            $select->remove($fh);
            next;
        }
        else {
            if ( $fh == $out ) {
                $buffer .= $line;
            }
            else {
                die("impossible... somehow got a filehandle i dont know about!");
            }
        }
    }
}
like( $buffer, $echo_result_regex, "safe_open3 read out" );
waitpid( $pid, 0 );
my $exit_code = $? >> 8;
ok( !$exit_code, "safe_open3 exited $exit_code" );

my $three_line_file_path = File::Spec->catfile( $test_dir, 'three_line_file.txt' );
$command = ( ( $^O =~ /MSWin32/ ) ? 'type ' : 'cat ' ) . $three_line_file_path;
$runner = IPC::Open3::Callback->new();
my @lines = ();
$runner->run_command(
    $command,
    {   buffer_output => 1,
        out_callback  => sub {
            push( @lines, shift );
        }
    }
);
is( scalar(@lines), 3, 'buffer_output number of calls' );
is_deeply( \@lines, [ 'three', 'line', 'file' ], 'buffer_output match' );

$temp_file = File::Temp->new();
open( $file_handle, '>', $temp_file );
$runner = IPC::Open3::Callback->new();
$command = ( ( $^O =~ /MSWin32/ ) ? 'type ' : 'cat ' ) . $three_line_file_path;
$runner->run_command( $command, { out_handle => $file_handle } );
close($file_handle);
is( do { local ( @ARGV, $/ ) = $temp_file;            <> },
    do { local ( @ARGV, $/ ) = $three_line_file_path; <> },
    'piped out handle'
);

open( my $three_line_file, '<', $three_line_file_path );
if ( $^O =~ /MSWin32/ ) {
    $command  = 'more';
    $expected = "three\r\nline\r\nfile\r\n";
}
else {
    $command  = 'cat';
    $expected = "three\nline\nfile\n";
}
$runner = IPC::Open3::Callback->new();
$buffer = '';
$runner->run_command(
    $command,
    {   in_handle    => $three_line_file,
        out_callback => sub {
            $buffer .= shift;
        }
    }
);
is( $buffer, $expected, 'piped in handle' );
close($three_line_file);

$runner = IPC::Open3::Callback->new();
my $killed;
$buffer    = '';
$exit_code = $runner->run_command(
    "cat $three_line_file_path",
    {   buffer_output => 1,
        out_callback  => sub {
            my ( $data, $pid ) = @_;
            if ( $data =~ /line/ ) {
                if ( $pid =~ /^\d+$/ ) {
                    $killed = 1;
                    kill( 9, $pid );
                }
            }
            return if ($killed);
            $buffer .= $data;
        }
    }
);
ok( $killed, 'got pid to kill' );
is( $buffer, 'three', 'short circuit' );



( run in 2.221 seconds using v1.01-cache-2.11-cpan-364913b4093 )