2014-02-25 12:49:21 +01:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
use IPC::Open2;
|
|
|
|
use Fcntl qw/:flock/;
|
2014-02-27 17:31:31 +01:00
|
|
|
use POSIX ":sys_wait_h";
|
|
|
|
use Linux::Pid qw/getppid/;
|
2014-02-25 12:49:21 +01:00
|
|
|
|
|
|
|
my $outfile = '.output';
|
|
|
|
|
|
|
|
sub write_output {
|
|
|
|
my ($msg) = @_;
|
|
|
|
|
|
|
|
print "output: writing [$msg]\n";
|
|
|
|
|
|
|
|
open my $fh, '>>', $outfile;
|
|
|
|
flock $fh, LOCK_EX;
|
|
|
|
print $fh "$msg\n";
|
|
|
|
print "output: wrote [$msg]\n";
|
|
|
|
close $fh;
|
|
|
|
}
|
|
|
|
|
2014-02-27 17:31:31 +01:00
|
|
|
sub merge_file {
|
|
|
|
my ($file, $pid) = @_;
|
2014-02-25 12:49:21 +01:00
|
|
|
|
|
|
|
# create empty file
|
|
|
|
open my $fh, '>', $file;
|
|
|
|
close $fh;
|
|
|
|
|
|
|
|
my ($out, $in);
|
2014-02-27 17:31:31 +01:00
|
|
|
open2 $out, $in, "tail -q -F $file --pid=$pid";
|
2014-02-25 12:49:21 +01:00
|
|
|
print "merging $file to $outfile\n";
|
|
|
|
while(my $line = <$out>) {
|
|
|
|
chomp $line;
|
2014-02-27 17:31:31 +01:00
|
|
|
if(getppid == 1) {
|
|
|
|
print "$file: Parent died, exiting\n";
|
|
|
|
exit;
|
|
|
|
}
|
2014-02-25 12:49:21 +01:00
|
|
|
print "$file: got [$line]\n";
|
|
|
|
write_output $line;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-27 17:31:31 +01:00
|
|
|
sub merge {
|
|
|
|
my ($file) = @_;
|
|
|
|
|
|
|
|
my $pid = fork;
|
|
|
|
die "fork failed: $!" if not defined $pid;
|
|
|
|
|
|
|
|
if($pid == 0) {
|
|
|
|
print "$file pid: $$\n";
|
|
|
|
while(1) {
|
|
|
|
merge_file $file, $$;
|
|
|
|
print "merge $file killed, restarting...\n";
|
|
|
|
}
|
|
|
|
exit;
|
|
|
|
} else {
|
|
|
|
return $pid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
my ($gdb_pid, $prog_pid);
|
|
|
|
|
|
|
|
sub merge_outputs {
|
|
|
|
$gdb_pid = merge '.gdb_output';
|
|
|
|
$prog_pid = merge '.prog_output';
|
|
|
|
|
|
|
|
print "merge_outputs: gdb_pid: $gdb_pid; prog_pid: $prog_pid\n";
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
sleep 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$SIG{CHLD} = \&REAPER;
|
|
|
|
sub REAPER {
|
|
|
|
my $stiff;
|
|
|
|
while (($stiff = waitpid(-1, &WNOHANG)) > 0) {
|
|
|
|
print "child died: $stiff\n";
|
|
|
|
print "reaper: gdb_pid: $gdb_pid; prog_pid: $prog_pid\n";
|
2014-02-25 12:49:21 +01:00
|
|
|
|
2014-02-27 17:31:31 +01:00
|
|
|
if($stiff == $gdb_pid) {
|
|
|
|
$gdb_pid = merge '.gdb_output';
|
|
|
|
} elsif($stiff == $prog_pid) {
|
|
|
|
$prog_pid = merge '.prog_output';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$SIG{CHLD} = \&REAPER;
|
2014-02-25 12:49:21 +01:00
|
|
|
}
|
|
|
|
|
2014-02-27 17:31:31 +01:00
|
|
|
merge_outputs;
|