From 76764a06bf88d7f96c5a95a41e3961395034bace Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Thu, 14 Sep 2017 19:10:21 -0700 Subject: [PATCH] Use JSON to communicate wtih compiler VM --- modules/compiler_vm/compiler_client.pl | 18 ++-- modules/compiler_vm/compiler_vm_server.pl | 103 +++++++++------------- modules/compiler_vm/languages/_default.pm | 18 ++-- 3 files changed, 62 insertions(+), 77 deletions(-) diff --git a/modules/compiler_vm/compiler_client.pl b/modules/compiler_vm/compiler_client.pl index f954f070..969b56dd 100755 --- a/modules/compiler_vm/compiler_client.pl +++ b/modules/compiler_vm/compiler_client.pl @@ -13,6 +13,7 @@ use warnings; use strict; use IO::Socket; +use JSON; my $sock = IO::Socket::INET->new( PeerAddr => '127.0.0.1', @@ -24,19 +25,18 @@ if(not defined $sock) { die $!; } -my $nick = shift @ARGV; -my $channel = shift @ARGV; -my $code = join ' ', @ARGV; +my $json = join ' ', @ARGV; +my $h = decode_json $json; +my $lang = $h->{lang} // "c11"; -my $lang = "c11"; - -if($code =~ s/-lang=([^ ]+)//) { +if ($h->{code} =~ s/-lang=([^ ]+)//) { $lang = lc $1; } -print $sock "compile:$nick:$channel:$lang\n"; -print $sock "$code\n"; -print $sock "compile:end\n"; +$h->{lang} = $lang; +$json = encode_json $h; + +print $sock "$json\n"; while(my $line = <$sock>) { print "$line"; diff --git a/modules/compiler_vm/compiler_vm_server.pl b/modules/compiler_vm/compiler_vm_server.pl index 745bbc63..2fcdc085 100755 --- a/modules/compiler_vm/compiler_vm_server.pl +++ b/modules/compiler_vm/compiler_vm_server.pl @@ -9,6 +9,7 @@ use strict; use File::Basename; use POSIX; +use JSON; my $USERNAME = 'compiler'; my $USE_LOCAL = defined $ENV{'CC_LOCAL'}; @@ -62,72 +63,49 @@ sub run_server { while(my $line = <$input>) { chomp $line; + print "-" x 40, "\n"; print "Got [$line]\n"; - if($line =~ m/^compile:\s*end/) { - next if not defined $lang or not defined $code; + my $compile_in = decode_json($line); - print "Attempting compile [$lang] ...\n"; + print "Attempting compile [$compile_in->{lang}] ...\n"; - my $pid = fork; - - if (not defined $pid) { - print "fork failed: $!\n"; - next; - } - - if ($pid == 0) { - my ($uid, $gid) = (getpwnam $USERNAME)[2, 3]; - if (not $uid and not $gid) { - print "Could not find user $USERNAME: $!\n"; - exit; - } - - - POSIX::setgid($gid); - POSIX::setuid($uid); - - my $result = interpret($lang, $sourcefile, $execfile, $code, $cmdline, $user_input, $date); - - print "Done compiling; result: [$result]\n"; - print $output "result:$result\n"; - print $output "result:end\n"; - exit; - } else { - waitpid $pid, 0; - } - - if(not defined $USE_LOCAL or $USE_LOCAL == 0) { - print "input: "; - next; - } else { - exit; - } - } - - if($line =~ m/^compile:\s*(.*)/) { - my $options = $1; - $cmdline = undef; - $user_input = undef; - $lang = undef; - $sourcefile = undef; - $execfile = undef; - - ($lang, $sourcefile, $execfile, $cmdline, $user_input, $date) = split /:/, $options; - - $code = ""; - $sourcefile = "/dev/null" if not defined $sourcefile; - $execfile = "/dev/null" if not defined $execfile; - $lang = "unknown" if not defined $lang; - $cmdline = "echo No cmdline specified!" if not defined $cmdline; - $user_input = "" if not defined $user_input; - - print "Setting lang [$lang]; [$sourcefile]; [$cmdline]; [$user_input]; [$date]\n"; + my $pid = fork; + if (not defined $pid) { + print "fork failed: $!\n"; next; } - $code .= $line . "\n"; + if ($pid == 0) { + my ($uid, $gid) = (getpwnam $USERNAME)[2, 3]; + if (not $uid and not $gid) { + print "Could not find user $USERNAME: $!\n"; + exit; + } + + POSIX::setgid($gid); + POSIX::setuid($uid); + + my $result = interpret(%$compile_in); + + my $compile_out = { result => $result }; + my $json = encode_json($compile_out); + + print "Done compiling; result: [$result] [$json]\n"; + print $output "result:$json\n"; + print $output "result:end\n"; + exit; + } else { + waitpid $pid, 0; + } + + if(not defined $USE_LOCAL or $USE_LOCAL == 0) { + print "input: "; + next; + } else { + exit; + } } } else { while(1) { @@ -142,17 +120,16 @@ sub run_server { } sub interpret { - my ($lang, $sourcefile, $execfile, $code, $cmdline, $input, $date) = @_; + my %h = @_; - print "lang: [$lang], sourcefile: [$sourcefile], execfile [$execfile], code: [$code], cmdline: [$cmdline], input: [$input], date: [$date]\n"; + print "lang: [$h{lang}], sourcefile: [$h{sourcefile}], execfile [$h{execfile}], code: [$h{code}], cmdline: [$h{cmdline}], input: [$h{input}], date: [$h{date}]\n"; - $lang = '_default' if not exists $languages{$lang}; + $h{lang} = '_default' if not exists $languages{$h{lang}}; system("chmod -R 755 /home/compiler"); system("rm -rf /home/compiler/prog*"); - my $mod = $lang->new(sourcefile => $sourcefile, execfile => $execfile, code => $code, - cmdline => $cmdline, input => $input, date => $date); + my $mod = $h{lang}->new(%h); $mod->preprocess; diff --git a/modules/compiler_vm/languages/_default.pm b/modules/compiler_vm/languages/_default.pm index 2b11cd29..fa5cca44 100755 --- a/modules/compiler_vm/languages/_default.pm +++ b/modules/compiler_vm/languages/_default.pm @@ -17,6 +17,7 @@ use IO::Socket; use LWP::UserAgent; use Time::HiRes qw/gettimeofday/; use Text::Balanced qw/extract_delimited/; +use JSON; my $EXECUTE_PORT = '3333'; @@ -367,21 +368,28 @@ sub execute { print FILE "$cmdline\n$input\n$pretty_code\n"; close FILE; - print $compiler "compile:$self->{lang}:$self->{sourcefile}:$self->{execfile}:$cmdline:$input:$date\n"; - print $compiler "$pretty_code\n"; - print $compiler "compile:end\n"; + my $compile_in = { lang => $self->{lang}, sourcefile => $self->{sourcefile}, execfile => $self->{execfile}, + cmdline => $cmdline, input => $input, date => $date, arguments => $self->{arguments}, code => $pretty_code }; + my $compile_json = encode_json($compile_in); + + #print STDERR "Sending [$compile_json] to vm_server\n"; + + print $compiler "$compile_json\n"; my $result = ""; my $got_result = 0; while(my $line = <$compiler_output>) { - $line =~ s/[\r\n]+$//; + #print STDERR "Read [$line]\n"; + + $line =~ s/[\r\n]+$//; last if $line =~ /^result:end$/; if($line =~ /^result:/) { $line =~ s/^result://; - $result .= "$line\n"; + my $compile_out = decode_json($line); + $result .= "$compile_out->{result}\n"; $got_result = 1; next; }