Commit | Line | Data |
03ae33ef |
1 | #!/usr/bin/env perl |
2 | |
3 | use strictures 1; |
4 | use JSON::PP qw(encode_json decode_json); |
5 | use Eval::WithLexicals; |
6 | use Data::Dumper::Concise; |
7 | use IO::Handle; |
8 | |
9 | STDOUT->autoflush(1); |
10 | |
11 | my $eval = Eval::WithLexicals->new; |
12 | |
13 | sub out { |
14 | print STDOUT encode_json([ @_ ])."\n" |
15 | or die "Failed to print to STDOUT: $!"; |
16 | } |
17 | |
18 | sub run_eval { |
19 | my ($perl) = @_; |
20 | unless ($perl) { |
21 | out(MISTAKE => eval_input => "No code supplied"); |
22 | return; |
23 | } |
24 | if (my $ref = ref($perl)) { |
25 | out(MISTAKE => eval_input => "Code was a ${ref} reference"); |
26 | return; |
27 | } |
28 | my ($code, @ret); |
29 | open my $stdout, '>', \my $output; |
30 | open my $stderr, '>', \my $errors; |
31 | if (eval { |
32 | local *STDOUT = $stdout; |
33 | local *STDERR = $stderr; |
34 | @ret = $eval->eval($perl); |
35 | 1 |
36 | }) { |
37 | $code = 'OK'; |
38 | } else { |
39 | ($code, @ret) = (FAILURE => $@); |
40 | } |
41 | my $dumped_ret; |
42 | unless (eval { $dumped_ret = Dumper(@ret); 1 }) { |
43 | $dumped_ret = "Error dumping ${code} result: $@"; |
44 | $code = 'FAILURE'; |
45 | } |
46 | out($code => { stdout => $output, stderr => $errors, return => $dumped_ret }); |
47 | } |
48 | |
49 | while (my $line = <STDIN>) { |
50 | my $data = eval { decode_json($line) }; |
51 | if ($@) { |
52 | out(MISTAKE => invalid_json => $@); |
53 | next; |
54 | } |
55 | unless (ref($data) eq 'ARRAY') { |
56 | out(MISTAKE => message_format => "Not an ARRAY"); |
57 | next; |
58 | } |
59 | unless (@$data > 0) { |
60 | out(MISTAKE => message_format => "No message name"); |
61 | next; |
62 | } |
63 | if (my $ref = ref($data->[0])) { |
64 | out(MISTAKE => message_format => "Message name was a ${ref} ref"); |
65 | next; |
66 | } |
67 | my ($message, @args) = @{$data}; |
68 | if ($message eq 'EXIT') { |
69 | exit 0; |
70 | } elsif ($message eq 'EVAL') { |
71 | run_eval(@args); |
72 | } else { |
73 | out(MISTAKE => message_name => "Unknown message"); |
74 | } |
75 | } |