3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-26 13:59:47 +01:00

compiler-vm: added -input flag for providing stdin input; added %b printf specifier to print base-2; bug-fixes

This commit is contained in:
Pragmatic Software 2011-12-30 23:20:29 +00:00
parent dd7f84ceff
commit cf0fead036
7 changed files with 143 additions and 21 deletions

View File

@ -13,8 +13,8 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 342,
BUILD_DATE => "2011-12-17",
BUILD_REVISION => 343,
BUILD_DATE => "2011-12-30",
};
1;

View File

@ -1,6 +1,4 @@
#!/bin/sh
CC_LOCAL=1
export CC_LOCAL
ulimit -c 50000
./compiler_vm_client.pl compiler "$@"
CC_LOCAL=1 ./compiler_vm_client.pl compiler "$@"

View File

@ -27,7 +27,7 @@ sub server_listen {
sub vm_stop {
my $pid = shift @_;
return if not defined $pid;
kill 'TERM', $pid;
kill 9, $pid;
waitpid($pid, 0);
}
@ -39,7 +39,8 @@ sub vm_start {
}
if($pid == 0) {
my $command = 'qemu-system-x86_64 -M pc -hda /home/compiler/compiler-vm-image -m 128 -monitor tcp:127.0.0.1:4445,server,nowait -serial tcp:127.0.0.1:4444,server,nowait -boot c -loadvm 2 -nographic';
#system('cp /home/compiler/compiler-saved-vm-backup /home/compiler/compiler-saved-vm');
my $command = 'qemu-system-x86_64 -M pc -net none -hda /home/compiler/compiler-saved-vm -m 128 -monitor tcp:127.0.0.1:4445,server,nowait -serial tcp:127.0.0.1:4444,server,nowait -enable-kvm -boot c -nographic -loadvm 1';
my @command_list = split / /, $command;
exec(@command_list);
} else {
@ -47,9 +48,24 @@ sub vm_start {
}
}
sub vm_reset {
use IO::Socket;
my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 4445, Prot => 'tcp');
if(not defined $sock) {
print "Unable to connect to monitor: $!\n";
return;
}
print $sock "loadvm 1\n";
close $sock;
}
sub execute {
my ($cmdline) = @_;
print "execute($cmdline)\n";
my ($ret, $result);
my $child = fork;
@ -61,7 +77,7 @@ sub execute {
my $pid = open(my $fh, '-|', "$cmdline 2>&1");
local $SIG{ALRM} = sub { print "Time out\n"; kill 'TERM', $pid; die "Timed-out\n"; };
alarm(5);
alarm(7);
while(my $line = <$fh>) {
$result .= $line;
@ -71,21 +87,19 @@ sub execute {
my $ret = $? >> 8;
alarm 0;
print "[$ret, $result]\n";
return ($ret, $result);
};
alarm 0;
if($@ =~ /Timed-out/) {
#kill 'TERM', $child;
return (-13, '[Timed-out]');
}
print "[$ret, $result]\n";
return ($ret, $result);
} else {
waitpid($child, 0);
#print "child exited, parent continuing\n";
print "child exited, parent continuing\n";
return undef;
}
}
@ -99,19 +113,19 @@ sub compiler_server {
while (my $client = $server->accept()) {
$client->autoflush(1);
my $hostinfo = gethostbyaddr($client->peeraddr);
printf "[Connect from %s]\n", $hostinfo->name || $client->peerhost;
printf "[Connect from %s]\n", $client->peerhost;
eval {
my $lang;
my $nick;
my $code = "";
local $SIG{ALRM} = sub { die 'Timed-out'; };
alarm 1;
alarm 5;
while (my $line = <$client>) {
$line =~ s/[\r\n]+$//;
next if $line =~ m/^\s*$/;
alarm 1;
alarm 5;
print "got: [$line]\n";
if($line =~ /compile:end/) {
@ -124,7 +138,7 @@ sub compiler_server {
my ($ret, $result) = execute("./compiler_vm_client.pl $tnick -lang=$tlang $code");
if(not defined $ret) {
#print "parent continued\n";
print "parent continued\n";
last;
}
@ -137,6 +151,7 @@ sub compiler_server {
print $client $result . "\n";
close $client;
# child exit
print "child exit\n";
exit;
}

View File

@ -26,7 +26,7 @@ my %languages = (
);
my %preludes = (
'C99' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n",
'C99' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n#include <stdbool.h>\n#include \"prelude.h\"\n\n",
'C' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n",
'C++' => "#include <iostream>\n#include <cstdio>\n\nusing namespace std;\n\n",
);
@ -696,9 +696,12 @@ if($output =~ m/^\s*$/) {
my $right_quote = chr(226) . chr(128) . chr(153);
$output =~ s/$left_quote/'/g;
$output =~ s/$right_quote/'/g;
$output =~ s/\s*In function 'main':\s*//g;
$output =~ s/warning: unknown conversion type character 'b' in format\s+warning: too many arguments for format/info: conversion type character 'b' in format is a candide extension/g;
#$output =~ s/[\r\n]+/ /g;
#$output =~ s/\s+/ /g;
$output =~ s/[\r\n]+/ /g;
$output =~ s/\s+/ /g;
}
unless($got_run) {

View File

@ -138,7 +138,8 @@ sub interpret {
$output = "[$result]\n";
}
($ret, $result) = execute(5, "./compiler_watchdog.pl");
my $user_input_quoted = quotemeta $user_input;
($ret, $result) = execute(5, "./compiler_watchdog.pl $user_input_quoted");
$result =~ s/^\s+//;
$result =~ s/\s+$//;

View File

@ -165,6 +165,8 @@ sub reaper {
}
}
my $stdin_input = join ' ', @ARGV;
sub execute {
my ($cmdline) = @_;
my ($ret, $result);
@ -176,7 +178,17 @@ sub execute {
local $SIG{TERM} = sub { kill 'TERM', $child; };
if($child == 0) {
exec("$cmdline 2>&1");
if(length $stdin_input) {
my ($out, $in);
open2($out, $in, "$cmdline 2>&1");
print $in "$stdin_input\n";
while(<$out>) {
print $_ . "\n";
}
exit 0;
} else {
exec("$cmdline 2>&1");
}
} else {
while(1) { sleep 10; }
}

View File

@ -0,0 +1,93 @@
#if 1
#include <limits.h>
#include <wchar.h>
#include <stdio.h>
#include <printf.h>
#include <locale.h>
static int printf_binary_handler(FILE *s, const struct printf_info *info, const void *const *args)
{
const char *g = 0;
struct lconv *loc = 0;
int group = 0, arr = 0, total = 0, len, digits;
unsigned long long value = info->is_long_double ? *(const unsigned long long *)args[0] :
info->is_long ? *(const unsigned long *) args[0] :
info->is_char ? *(const unsigned char *) args[0] :
info->is_short ? *(const unsigned short *) args[0] :
*(const unsigned int *) args[0] ;
char buf[sizeof value * CHAR_BIT], *p = buf;
while(value) *p++ = '0' + (value & 1), value >>= 1;
len = p - buf;
digits = info->prec < 0 ? 1 : info->prec;
if(len > digits) digits = len;
if(info->alt) {
if(digits += -digits & 3) total = digits + (digits - 1) / 4 * !!info->group;
} else {
total = digits;
group = info->group && (loc = localeconv(), *(g = loc->grouping));
if(group) {
while(*g > 0 && *g < CHAR_MAX) {
if(digits - arr <= *g) break;
++total;
arr += *g++;
}
if(!*g) total += (digits - arr - 1) / g[-1];
}
}
while(!info->left && info->width > total++) fprintf(s, "%lc", (wint_t)info->pad);
if(info->alt)
while(digits) {
fputc(digits-- > len ? '0' : *--p, s);
if(digits && !(digits % 4) && info->group) fputc('.', s);
}
else if(group) {
if(*g) {
while(digits > arr) fputc(digits-- > len ? '0' : *--p, s);
} else {
int j = (digits - arr) % g[-1];
if(!j) j = g[-1];
while(j--) fputc(digits-- > len ? '0' : *--p, s);
while(digits > arr) {
fputs(loc->thousands_sep, s);
for(j = 0; j < g[-1]; ++j) fputc(digits-- > len ? '0' : *--p, s);
}
}
while(digits) {
int i = *--g;
fputs(loc->thousands_sep, s);
while(i--) fputc(digits-- > len ? '0' : *--p, s);
}
} else while(digits) fputc(digits-- > len ? '0' : *--p, s);
while(info->left && info->width > total++) fputc(' ', s);
return total - 1;
}
static int printf_binary_arginfo(const struct printf_info *info, size_t n, int *types, int *sizes)
{
if(n < 1) return -1;
(void)sizes;
types[0] = info->is_long_double ? PA_INT | PA_FLAG_LONG_LONG :
info->is_long ? PA_INT | PA_FLAG_LONG :
info->is_char ? PA_CHAR :
info->is_short ? PA_INT | PA_FLAG_SHORT :
PA_INT ;
return 1;
}
__attribute__ (( constructor )) static void printf_binary_register(void)
{
setlocale(LC_ALL, "");
register_printf_specifier('b', printf_binary_handler, printf_binary_arginfo);
}
#endif
#define STR(s) #s
#define REVEAL(s) STR(s)