X-Git-Url: http://git.ieval.ro/?p=gruntmaster-daemon.git;a=blobdiff_plain;f=lib%2FGruntmaster%2FDaemon%2FFormat.pm;h=5f503a117a534a4749294611034e2315dc8ebe93;hp=93035ddc9d8c1337d4919578e0b2616f955ae07e;hb=fdb99417bb13ca0418a5ec8d9e240e29565225c4;hpb=7be8c37d42b6782bc5d94ea4e52dd1261ce6e3ae diff --git a/lib/Gruntmaster/Daemon/Format.pm b/lib/Gruntmaster/Daemon/Format.pm index 93035dd..5f503a1 100644 --- a/lib/Gruntmaster/Daemon/Format.pm +++ b/lib/Gruntmaster/Daemon/Format.pm @@ -6,35 +6,62 @@ use warnings; use parent qw/Exporter/; no if $] > 5.017011, warnings => 'experimental::smartmatch'; -use POSIX qw//; +use Expect::Simple; use File::Basename qw/fileparse/; use File::Slurp qw/read_file write_file/; -use Gruntmaster::Daemon::Constants qw/TLE OLE DIED NZX/; -use Time::HiRes qw/alarm/; use List::MoreUtils qw/natatime/; use Log::Log4perl qw/get_logger/; -use IPC::Signal qw/sig_name sig_num/; +use POSIX qw/mkfifo/; +use String::ShellQuote qw/shell_quote/; use Try::Tiny; our $VERSION = "5999.000_004"; -our @EXPORT_OK = qw/prepare_files/; +our @EXPORT_OK = qw/prepare_files stopvms/; ################################################## +our (%vm); + +sub runvm { + my ($name) = @_; + return unless $ENV{GRUNTMASTER_VM}; + mkfifo "$name.in", 0600; + mkfifo "$name.out", 0600; + get_logger->trace("Starting VM $name"); + $vm{$name} = Expect::Simple->new({ + Cmd => "$ENV{GRUNTMASTER_VM} $name", + Prompt => '# ', + DisconnectCmd => 'exit', + RawPty => 1, + Timeout => 10, + }); +} + +sub stopvms { %vm = () } + sub execlist { - my (@args) = @_; - my $ret = fork // die 'Cannot fork'; - if ($ret) { - waitpid $ret, 0; - die "gruntmaster-exec died\n" if -z 'exec-result'; - my ($excode, $exmsg) = read_file 'exec-result'; - unlink 'exec-result'; - chomp ($excode, $exmsg); - die [$excode, $exmsg] if $excode > 0; + my ($vm, @args) = @_; + my $er = "exec-result-$vm"; + if ($vm{$vm}) { + my $cmd = ">$er " . shell_quote 'gruntmaster-exec', @args; + get_logger->trace("Running in VM $vm: $cmd"); + $vm{$vm}->send($cmd); } else { - open STDOUT, '>exec-result'; - exec 'gruntmaster-exec', @args; + my $ret = fork // die 'Cannot fork'; + if ($ret) { + waitpid $ret, 0; + } else { + open STDOUT, ">$er"; + exec 'gruntmaster-exec', @args; + } } + + die "gruntmaster-exec died\n" if -z $er; + my ($excode, $exmsg) = read_file $er; + unlink $er; + chomp ($excode, $exmsg); + get_logger->trace("Exec result: $excode $exmsg"); + die [$excode, $exmsg] if $excode > 0; } sub command_and_args{ @@ -66,7 +93,7 @@ sub mkrun{ while (my ($fd, $file) = $it->()) { push @args, "--fd=$fd $file"; } - execlist @args, command_and_args($format, $basename); + execlist $basename, @args, command_and_args($format, $basename); } } @@ -75,7 +102,7 @@ sub prepare{ get_logger->trace("Preparing file $name..."); try { - execlist '--fd=1 >>errors', '--fd=2 >>errors', 'gruntmaster-compile', $format, $name; + execlist prog => '--fd=1 >>errors', '--fd=2 >>errors', 'gruntmaster-compile', $format, $name; } catch { die "Compile error\n" } finally { @@ -87,6 +114,7 @@ sub prepare{ sub prepare_files{ my $meta = shift; + runvm $_ for keys %{$meta->{files}}; for my $file (values %{$meta->{files}}) { my ($format, $name, $content) = @{$file}{qw/format name content/};