kentfredric (owner)

Revisions

gist: 214645 Download_button fork
public
Public Clone URL: git://gist.github.com/214645.git
Embed All Files: show embed
IO::OpenFused #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/perl
 
use strict;
use warnings;
 
use POSIX qw( dup pipe );
use IO::File;
use IO::Handle;
use Data::Dump qw( dump );
 
sub openstream {
    my ( $fhx, @rest ) = @_;
 
    # Copy STDOUT and STDERR for resurrection.
 
    my $oldstdout = dup( fileno(*STDOUT) );
    my $oldstderr = dup( fileno(*STDERR) );
 
    # Generate a pipe to accept data from child process.
    my ( $response_r, $response_w ) = POSIX::pipe();
 
    # Put Perl handles on the pipe.
    my $responder = IO::Handle->new->fdopen( $response_r, 'r' );
    my $writer = IO::Handle->new->fdopen( $response_w, 'w' );
    my $tstdout = IO::Handle->new->fdopen( $oldstdout, 'w' );
    $responder->autoflush(1);
    $writer->autoflush(1);
    $tstdout->autoflush(1);
 
    # Return the handle to the user.
    $_[0] = $responder;
 
    # Reopen STDERR and STDOUT to point to the pipe.
    open *STDERR, '>>&=', $response_w;
    open *STDOUT, '>>&=', $response_w;
  
    # Run the users app with the new stuff.
    {
        if( not my $pid = fork() ){
select *STDERR; $|++;
     select *STDOUT; $|++;
            system @rest;
            exit;
        }
    }
    open *STDERR, '>>&=', $oldstderr;
    open *STDOUT, '>>&=', $oldstdout;
}
 
openstream my $fh, qw( perl evil.pl );
 
while ( my $line = <$fh> ) {
    print dump $line;
}