X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Futils%2Fpintos;h=40a240ce974a66c0d590597be4bed25bed0e52dd;hb=b2b1f040894e1db4fec9e5ee9efc2fcca5f9829c;hp=8b3b56d7fa2aeb4e5b5a33576181a830f51cd0fc;hpb=ed8a11cc772b5f0a10361adb410503831ae89c7b;p=pintos-anon diff --git a/src/utils/pintos b/src/utils/pintos index 8b3b56d..40a240c 100755 --- a/src/utils/pintos +++ b/src/utils/pintos @@ -1,6 +1,7 @@ #! /usr/bin/perl -w use strict; +use POSIX; our ($mem) = 4; our ($serial_out) = 1; @@ -22,17 +23,17 @@ GetOptions ("sim=s" => sub { set_sim (@_) }, "no-debug" => sub { set_debug ("no-debug") }, "monitor" => sub { set_debug ("monitor") }, "gdb" => sub { set_debug ("gdb") }, - + "run|get|put|make-disk" => \&cmd_option, - + "m|memory=i" => \$mem, "j|jitter=i" => sub { set_jitter (@_) }, "r|realtime" => sub { set_realtime () }, - + "v|no-vga" => sub { set_vga ('none'); }, "s|no-serial" => sub { $serial_out = 0; }, "t|terminal" => sub { set_vga ('terminal'); }, - + "h|help" => sub { usage (0); }, "0|os-disk|disk-0|hda=s" => \$disks[0], @@ -89,7 +90,7 @@ die "no command specified; use --help for help\n" 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; @@ -112,7 +113,7 @@ if ($cmd eq 'run') { # Create scratch disk from file. die "$hostfn: $!\n" if ! -e $hostfn; my ($size) = -s _; - if ($size) { + if ($size) { copy_pad ($hostfn, "scratch.dsk", 512); } else { open (SCRATCH, ">scratch.dsk") or die "scratch.dsk: create: $!\n"; @@ -123,9 +124,7 @@ if ($cmd eq 'run') { # 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; @@ -142,7 +141,7 @@ if ($cmd eq 'run') { 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"; @@ -157,8 +156,6 @@ if ($cmd eq 'run') { print DST $src or die "$hostfn: write error\n"; close (DST); close (SRC); - - exit 1; } elsif ($cmd eq 'help') { usage (0); } else { @@ -212,14 +209,14 @@ sub create_disk { } sub run_vm { - my ($fork) = shift; - $fork eq 'FORK' || $fork eq 'EXEC' or die; + my (@args) = @_; our (@disks); die "$disks[0]: can't find OS disk\n" if ! -e $disks[0]; + die "$disks[0]: OS disk cannot have zero size\n" if ! -s $disks[0]; for my $i (1...3) { - undef $disks[$i] if ! -e $disks[$i]; + undef $disks[$i] if ! -s $disks[$i]; } if (my ($project) = `pwd` =~ /\b(threads|userprog|vm|filesys)\b/) { @@ -234,7 +231,7 @@ sub run_vm { } } - write_cmd_line ($disks[0], @_); + write_cmd_line ($disks[0], @args); if ($sim eq 'bochs') { my ($bin); @@ -281,7 +278,16 @@ sub run_vm { 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'; @@ -298,7 +304,6 @@ sub run_vm { 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'; @@ -353,14 +358,36 @@ sub run_vm { } 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"); + } +} - exit 1; +sub relay_signal { + my ($pid, $signal) = @_; + kill $signal, $pid; + $SIG{$signal} = 'DEFAULT'; + kill $signal, getpid (); +} + +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 $?; } } @@ -381,7 +408,7 @@ sub write_cmd_line { sub run_command { print join (' ', @_), "\n"; - die "command failed\n" if system (@_); + die "command failed\n" if xsystem (@_); } sub search_path {