line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Gruntmaster::Daemon::Format; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
59
|
use 5.014000; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
77
|
|
4
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
59
|
|
5
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
122
|
|
6
|
2
|
|
|
2
|
|
10
|
use parent qw/Exporter/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
12
|
|
7
|
2
|
|
|
2
|
|
2821
|
no if $] > 5.017011, warnings => 'experimental::smartmatch'; |
|
2
|
|
|
|
|
201
|
|
|
2
|
|
|
|
|
15
|
|
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
2826
|
use POSIX qw//; |
|
2
|
|
|
|
|
32307
|
|
|
2
|
|
|
|
|
66
|
|
10
|
2
|
|
|
2
|
|
20
|
use File::Basename qw/fileparse/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
229
|
|
11
|
2
|
|
|
2
|
|
2626
|
use File::Slurp qw/write_file/; |
|
2
|
|
|
|
|
21338
|
|
|
2
|
|
|
|
|
216
|
|
12
|
2
|
|
|
2
|
|
23
|
use Gruntmaster::Daemon::Constants qw/TLE OLE DIED NZX/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
115
|
|
13
|
2
|
|
|
2
|
|
3827
|
use Time::HiRes qw/alarm/; |
|
2
|
|
|
|
|
5206
|
|
|
2
|
|
|
|
|
10
|
|
14
|
2
|
|
|
2
|
|
5514
|
use List::MoreUtils qw/natatime/; |
|
2
|
|
|
|
|
3173
|
|
|
2
|
|
|
|
|
179
|
|
15
|
2
|
|
|
2
|
|
2806
|
use Log::Log4perl qw/get_logger/; |
|
2
|
|
|
|
|
135434
|
|
|
2
|
|
|
|
|
18
|
|
16
|
2
|
|
|
2
|
|
1981
|
use IPC::Signal qw/sig_name sig_num/; |
|
2
|
|
|
|
|
1421
|
|
|
2
|
|
|
|
|
5550
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = "5999.000_004"; |
19
|
|
|
|
|
|
|
our @EXPORT_OK = qw/prepare_files/; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
################################################## |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub command_and_args{ |
24
|
0
|
|
|
0
|
0
|
|
my ($format, $basename) = @_; |
25
|
|
|
|
|
|
|
|
26
|
0
|
|
|
|
|
|
given($format) { |
27
|
0
|
|
|
|
|
|
"./$basename" when [qw/C CPP GCCGO GOLANG HASKELL PASCAL/]; |
28
|
0
|
|
|
|
|
|
"./$basename.exe" when 'MONO'; |
29
|
0
|
|
|
|
|
|
java => $basename when 'JAVA'; |
30
|
0
|
|
|
|
|
|
perl => $basename when 'PERL'; |
31
|
0
|
|
|
|
|
|
python => $basename when 'PYTHON'; |
32
|
0
|
|
|
|
|
|
default { die "Don't know how to execute format $format" } |
|
0
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub mkrun{ |
37
|
0
|
|
|
0
|
0
|
|
my $format = shift; |
38
|
|
|
|
|
|
|
sub{ |
39
|
0
|
|
|
0
|
|
|
local *__ANON__ = 'mkrun_runner'; |
40
|
0
|
|
|
|
|
|
my ($name, %args) = @_; |
41
|
0
|
|
|
|
|
|
get_logger->trace("Running $name..."); |
42
|
0
|
|
|
|
|
|
my $basename = fileparse $name, qr/\.[^.]*/; |
43
|
0
|
|
0
|
|
|
|
my $ret = fork // die 'Cannot fork'; |
44
|
0
|
0
|
|
|
|
|
if ($ret) { |
45
|
0
|
|
|
|
|
|
my $tle; |
46
|
0
|
|
|
|
|
|
local $SIG{ALRM} = sub { kill KILL => $ret; $tle = 1}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
47
|
0
|
0
|
|
|
|
|
alarm $args{timeout} if exists $args{timeout}; |
48
|
0
|
|
|
|
|
|
waitpid $ret, 0; |
49
|
0
|
|
|
|
|
|
alarm 0; |
50
|
0
|
|
|
|
|
|
my $sig = $? & 127; |
51
|
0
|
|
|
|
|
|
my $signame = sig_name $sig; |
52
|
0
|
0
|
|
|
|
|
die [TLE, "Time Limit Exceeded"] if $tle; |
53
|
0
|
0
|
0
|
|
|
|
die [OLE, 'Output Limit Exceeded'] if $sig && $signame eq 'XFSZ'; |
54
|
0
|
0
|
0
|
|
|
|
die [DIED, "Crash (SIG$signame)"] if $sig && $signame ne 'PIPE'; |
55
|
0
|
0
|
|
|
|
|
die [NZX, "Non-zero exit status: " . ($? >> 8)] if $? >> 8; |
56
|
|
|
|
|
|
|
} else { |
57
|
0
|
0
|
|
|
|
|
my @fds = exists $args{fds} ? @{$args{fds}} : (); |
|
0
|
|
|
|
|
|
|
58
|
0
|
|
|
|
|
|
$^F = 50; |
59
|
0
|
|
|
|
|
|
POSIX::close $_ for 0 .. $^F; |
60
|
0
|
|
|
|
|
|
my $it = natatime 2, @fds; |
61
|
0
|
|
|
|
|
|
while (my ($fd, $file) = $it->()) { |
62
|
0
|
0
|
|
|
|
|
open my $fh, $file or die $!; |
63
|
0
|
|
|
|
|
|
my $oldfd = fileno $fh; |
64
|
0
|
0
|
|
|
|
|
if ($oldfd != $fd) { |
65
|
0
|
0
|
|
|
|
|
POSIX::dup2 $oldfd, $fd or die $!; |
66
|
0
|
0
|
|
|
|
|
POSIX::close $oldfd or die $!; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
} |
69
|
0
|
0
|
0
|
|
|
|
exec 'gruntmaster-exec', $args{mlimit} // 0, $args{olimit} // 0, command_and_args($format, $basename), exists $args{args} ? @{$args{args}} : (); |
|
0
|
|
0
|
|
|
|
|
70
|
0
|
|
|
|
|
|
exit 42 |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
} |
73
|
0
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub prepare{ |
76
|
0
|
|
|
0
|
0
|
|
my ($name, $format) = @_; |
77
|
0
|
|
|
|
|
|
get_logger->trace("Preparing file $name..."); |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
$Gruntmaster::Daemon::errors .= `gruntmaster-compile $format $name 2>&1`; |
80
|
0
|
|
|
|
|
|
$Gruntmaster::Daemon::errors .= "\n"; |
81
|
0
|
0
|
|
|
|
|
die 'Compile error' if $? |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub prepare_files{ |
85
|
0
|
|
|
0
|
1
|
|
my $meta = shift; |
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
for my $file (values $meta->{files}) { |
88
|
0
|
|
|
|
|
|
my ($format, $name, $content) = @{$file}{qw/format name content/}; |
|
0
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
|
90
|
0
|
|
|
|
|
|
$file->{run} = mkrun($format); |
91
|
0
|
|
|
|
|
|
write_file $name, $content; |
92
|
0
|
|
|
|
|
|
prepare $name, $format; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
1; |
97
|
|
|
|
|
|
|
__END__ |