print "Child terminated with signal $signal\n";
}
- my ($exp_status) = !defined ($options{EXPECT}) ? 0 : $options{EXPECT};
- $result = WIFEXITED ($status) && WEXITSTATUS ($status) == $exp_status
- ? "ok" : "error";
+ $result = $status == 0 ? "ok" : "error";
}
-
if ($result eq 'error' && defined $options{DIE}) {
my ($msg) = $options{DIE};
if (defined ($log)) {
sub run_pintos {
my ($cmd_line, %args) = @_;
- $args{EXPECT} = 1 unless defined $args{EXPECT};
my ($retval) = xsystem ($cmd_line, %args);
return 'ok' if $retval eq 'ok';
return "Timed out after $args{TIMEOUT} seconds" if $retval eq 'timeout';
our ($formatted) = 0;
unlink $fs_disk;
-xsystem (0, "$pintos make-disk '$fs_disk' 2");
+xsystem ("$pintos make-disk '$fs_disk' 2");
while (@ARGV) {
put_file (shift (@ARGV));
}
my ($cmd) = "$pintos -v --os-disk='$os_disk' --fs-disk='$fs_disk' put";
$cmd .= " -f", $formatted = 1 if !$formatted;
$cmd .= " '$fn'";
- xsystem (1, $cmd);
+ xsystem ($cmd);
}
sub xsystem {
- my ($expect, $cmd) = @_;
+ my ($cmd) = @_;
print "$cmd\n";
- my ($code) = system ($cmd);
- WIFEXITED ($code) && WEXITSTATUS ($code) == $expect
- or die "command failed\n";
+ system ($cmd) == 0 or die "command failed\n";
}
#! /usr/bin/perl -w
use strict;
+use POSIX;
our ($mem) = 4;
our ($serial_out) = 1;
if @ARGV < 1;
my ($cmd) = shift @ARGV;
if ($cmd eq 'run') {
- run_vm ('EXEC', @ARGV);
+ run_vm (@ARGV);
} elsif ($cmd eq 'make-disk') {
usage () if @ARGV != 2;
my ($file, $mb) = @ARGV;
# Do copy.
my (@cmd) = ("-ci", $guestfn, $size, "-q");
unshift (@cmd, "-f") if $format;
- run_vm ('EXEC', @cmd);
-
- exit 1;
+ run_vm (@cmd);
} elsif ($cmd eq 'get') {
usage () if @ARGV != 1 && @ARGV != 2;
my ($guestfn, $hostfn) = @ARGV;
if $scratch_size < $fs_size + 16384;
# Do copy.
- run_vm ('FORK', "-co", $guestfn, "-q");
+ run_vm ("-co", $guestfn, "-q");
# Read out scratch disk.
print "copying $guestfn from $disks[2] to $hostfn...\n";
print DST $src or die "$hostfn: write error\n";
close (DST);
close (SRC);
-
- exit 1;
} elsif ($cmd eq 'help') {
usage (0);
} else {
}
sub run_vm {
- my ($fork) = shift;
- $fork eq 'FORK' || $fork eq 'EXEC' or die;
+ my (@args) = @_;
our (@disks);
}
}
- write_cmd_line ($disks[0], @_);
+ write_cmd_line ($disks[0], @args);
if ($sim eq 'bochs') {
my ($bin);
my (@cmd) = ($bin, '-q');
push (@cmd, '-j', $jitter) if defined $jitter;
print join (' ', @cmd), "\n";
- $fork eq 'EXEC' ? exec (@cmd) : system (@cmd);
+ my ($exit) = xsystem (@cmd);
+ if (WIFEXITED ($exit)) {
+ # Bochs exited normally.
+ # Ignore the exit code; Bochs normally exits with status 1,
+ # which is weird.
+ } elsif (WIFSIGNALED ($exit)) {
+ die "Bochs died with signal ", WTERMSIG ($exit), "\n";
+ } else {
+ die "Bochs died: code $exit\n";
+ }
} elsif ($sim eq 'qemu') {
print "warning: qemu doesn't support --terminal\n"
if $vga eq 'terminal';
push (@cmd, '-S') if $debug eq 'monitor';
push (@cmd, '-s') if $debug eq 'gdb';
run_command (@cmd);
- exit 1;
} elsif ($sim eq 'gsx') {
print "warning: VMware GSX Server doesn't support --$debug\n"
if $debug ne 'no-debug';
}
close (VMX);
- use Cwd;
my ($vmx) = getcwd () . "/pintos.vmx";
system ("vmware-cmd -s register $vmx >&/dev/null");
system ("vmware-cmd $vmx stop hard >&/dev/null");
system ("vmware -l -G -x -q $vmx");
system ("vmware-cmd $vmx stop hard >&/dev/null");
+ }
+}
+
+sub relay_signal {
+ my ($pid, $signal) = @_;
+ kill $signal, $pid;
+ $SIG{$signal} = 'DEFAULT';
+ kill $signal, getpid ();
+}
- exit 1;
+sub xsystem {
+ my ($pid) = fork;
+ if (!defined ($pid)) {
+ # Fork failed.
+ die "fork: $!\n";
+ } elsif (!$pid) {
+ # Running in child process.
+ exec (@_);
+ exit (1);
+ } else {
+ # Running in parent process.
+ local $SIG{INT} = sub { relay_signal ($pid, "INT"); };
+ local $SIG{TERM} = sub { relay_signal ($pid, "TERM"); };
+ waitpid ($pid, 0);
+ return $?;
}
}
sub run_command {
print join (' ', @_), "\n";
- die "command failed\n" if system (@_);
+ die "command failed\n" if xsystem (@_);
}
sub search_path {