AnyEvent-MCP
view release on metacpan or search on metacpan
return if $lines and $line_truncated;
return unless length $data;
my $remaining = $byte_limit - (length $stdout) - (length $stderr);
$truncated = 1 if length $data > $remaining;
$$target .= substr $data, 0, $remaining
if $remaining > 0;
if ($lines and $line_limit and ($$target =~ tr/\n//) > $line_limit) {
my $end = -1;
$end = index $$target, "\n", $end + 1
for 1 .. $line_limit;
substr $$target, $end + 1, length $$target, "";
$truncated = $line_truncated = 1;
return 1
}
0
};
proc_run $req, $command, $input, $timeout,
sub {
my ($handle) = @_;
my $stop = $capture->(\$stdout, $handle->{rbuf}, 1);
$handle->{rbuf} = "";
$stop
},
sub {
my ($handle) = @_;
$capture->(\$stderr, $handle->{rbuf}, 0);
$handle->{rbuf} = "";
0
},
sub {
my ($status, $timed_out, $failure) = @_;
return $done->(0, $failure) if $failure;
$done->(1, +{
stdout => $stdout,
stderr => $stderr,
exit => $status >> 8,
signal => $status & 127,
timed_out => $timed_out ? JSON::XS::true : JSON::XS::false,
truncated => $truncated || $timed_out ? JSON::XS::true : JSON::XS::false,
});
};
}
my $perl_slave = q{#perl
binmode STDIN;
binmode STDOUT;
$SIG{PIPE} = "IGNORE";
$| = 1;
for (;;) {
4 == read STDIN, my $buf, 4
or last;
my $len = unpack "N", $buf;
$len == read STDIN, $buf, $len
or die "short perl frame\n";
my @result = do {
(my $source, local @ARGV) = unpack "(w/a*)*", $buf;
("+", eval $source)
};
@result = ("-", $@)
if $@;
print pack "N/a*", pack "(w/a*)*", @result
or die "stdout: $!\n"
}
};
sub perl_frame {
pack "N/a*", pack "(w/a*)*", @_
}
my $perl_worker;
sub perl_eval {
my ($req, $workdir, $sandbox_grants, $source, $args, $timeout, $done) = @_;
my @command = ((fs_sandbox $workdir, $sandbox_grants), $perl, "-e", $perl_slave);
my $key = pack "(w/a*)*", @command;
my $io = $perl_worker;
undef $perl_worker;
if ($io && ($io->{perl_key} ne $key || !$io->{proc}{pid})) {
proc_destroy $io;
undef $io;
}
unless ($io) {
$io = proc_spawn @command;
$io->{rbuf_max} = (1 << 20) + 4096;
$io->{perl_key} = $key;
weaken (my $this = $io);
my $idle_destroy = sub {
my $io = $this or return;
undef $perl_worker if $perl_worker && $perl_worker == $io;
proc_destroy $io;
};
my $idle_stderr = sub { $_[0]{rbuf} = "" };
$io->{perl_idle} = sub {
my ($io) = @_;
my $err = $io->{proc_err};
$io ->on_eof ($idle_destroy);
$io ->on_error ($idle_destroy);
$err->on_eof ($idle_destroy);
$err->on_error ($idle_destroy);
$err->on_read ($idle_stderr );
$io ->on_read ($idle_destroy);
};
proc_on_exit $io->{proc}, sub {
my $io = $this or return;
$io->{perl_on_exit}->($_[0]) if $io->{perl_on_exit};
( run in 0.803 second using v1.01-cache-2.11-cpan-ac8be02dad9 )