]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/perl | |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use Fcntl; | |
6 | use POSIX ":sys_wait_h"; | |
7 | use IPC::Open3; | |
8 | use IO::Handle; | |
9 | use IO::Select; | |
10 | ||
11 | my $out = shift @ARGV; | |
12 | die unless @ARGV; | |
13 | ||
14 | open my $fout, ">>", $out or die "Can't write to $out: $!" if $out; | |
15 | ||
16 | my $select = IO::Select->new(); | |
17 | my $alive = 1; | |
18 | my $pid; | |
19 | ||
20 | my $code; | |
21 | sub sigchld | |
22 | { | |
23 | my $kid; | |
24 | do { | |
25 | $kid = waitpid( -1, WNOHANG ); | |
26 | if ( $kid == $pid ) { | |
27 | $code = $? >> 8; | |
28 | $alive = 0 | |
29 | } | |
30 | } while ( $kid > 0 ); | |
31 | } | |
32 | $SIG{CHLD} = \&sigchld; | |
33 | ||
34 | $pid = open3( "<&STDIN", \*child_out, \*child_err, @ARGV ); | |
35 | ||
36 | sub sethandle | |
37 | { | |
38 | my $h = shift; | |
39 | my $flags = 0; | |
40 | ||
41 | fcntl ( $h, F_GETFL, $flags ) | |
42 | or die "Couldn't get flags for HANDLE : $!\n"; | |
43 | $flags |= O_NONBLOCK; | |
44 | fcntl ( $h, F_SETFL, $flags ) | |
45 | or die "Couldn't set flags for HANDLE: $!\n"; | |
46 | ||
47 | $select->add( $h ); | |
48 | } | |
49 | ||
50 | sethandle( \*child_out ); | |
51 | sethandle( \*child_err ); | |
52 | ||
53 | while ( $alive ) { | |
54 | foreach my $h ( $select->can_read() ) { | |
55 | sysread $h, $_, 1024; | |
56 | print $fout $_ if $fout; | |
57 | if ( $h == \*child_err ) { | |
58 | print "\033[31m$_\033[0m"; | |
59 | } else { | |
60 | print $_; | |
61 | } | |
62 | STDOUT->flush(); | |
63 | } | |
64 | } | |
65 | ||
66 | exit $code; |