From: Ben Pfaff Date: Mon, 1 Nov 2004 05:33:30 +0000 (+0000) Subject: Add more tests. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;ds=sidebyside;h=ae20a83cc5ed14f276f2292d99079370562addc9;p=pintos-anon Add more tests. Fix - in makefile var bug reported by Jim. Make pintos util able to format and put in one step. --- diff --git a/grading/userprog/.cvsignore b/grading/userprog/.cvsignore index a438335..73d1273 100644 --- a/grading/userprog/.cvsignore +++ b/grading/userprog/.cvsignore @@ -1 +1,2 @@ *.d +*.dsk diff --git a/grading/userprog/Makefile b/grading/userprog/Makefile index 25ba857..e95e13f 100644 --- a/grading/userprog/Makefile +++ b/grading/userprog/Makefile @@ -1,12 +1,17 @@ SRCDIR = ../../src SINGLETONS = \ + $(addprefix args-, argc argv0 argvn single multiple dbl-space) \ + $(addprefix sc-, bad-sp bad-arg boundary) \ + halt exit \ $(addprefix create-, normal empty null bad-ptr long exists bound) \ - $(addprefix args-, argc argv0 argvn single multiple dbl-space) + $(addprefix open-, normal missing boundary empty null bad-ptr twice) \ + $(addprefix close-, normal twice stdin stdout bad-fd) \ + $(addprefix read-, normal bad-ptr boundary zero stdout bad-fd) define SINGLETON_PROG PROGS += $(1) -$(1)_SRC = $(1).c +$(subst -,_,$(1))_SRC = $(1).c endef $(foreach prog,$(SINGLETONS),$(eval $(call SINGLETON_PROG,$(prog)))) @@ -14,14 +19,8 @@ DISKS = $(patsubst %,%.dsk,$(PROGS)) disks: $(DISKS) -PINTOS = ../../src/utils/pintos -OS_DISK = ../../src/userprog/build/os.dsk %.dsk: % - rm -f $@.tmp - $(PINTOS) make-disk $@.tmp 2 - $(PINTOS) -v --os-disk=$(OS_DISK) --fs-disk=$@.tmp run -f -q - $(PINTOS) -v --os-disk=$(OS_DISK) --fs-disk=$@.tmp put $< - mv $@.tmp $@ + ./prep-disk $< clean:: rm -f $(DISKS) diff --git a/grading/userprog/close-bad-fd.c b/grading/userprog/close-bad-fd.c new file mode 100644 index 0000000..cdea3c5 --- /dev/null +++ b/grading/userprog/close-bad-fd.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(close-bad-fd) begin\n"); + close (0xc0101234); + printf ("(close-bad-fd) end\n"); + return 0; +} diff --git a/grading/userprog/close-bad-fd.exp b/grading/userprog/close-bad-fd.exp new file mode 100644 index 0000000..5ac59da --- /dev/null +++ b/grading/userprog/close-bad-fd.exp @@ -0,0 +1,6 @@ +(close-bad-fd) begin +(close-bad-fd) end +close-bad-fd: exit(0) +--OR-- +(close-bad-fd) begin +close-bad-fd: exit(-1) diff --git a/grading/userprog/close-normal.c b/grading/userprog/close-normal.c new file mode 100644 index 0000000..2b5e95d --- /dev/null +++ b/grading/userprog/close-normal.c @@ -0,0 +1,15 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(close-normal) begin\n"); + handle = open ("sample.txt"); + if (handle < 2) + printf ("(close-normal) fail: open() returned %d\n", handle); + close (handle); + printf ("(close-normal) end\n"); + return 0; +} diff --git a/grading/userprog/close-normal.exp b/grading/userprog/close-normal.exp new file mode 100644 index 0000000..f3be9bc --- /dev/null +++ b/grading/userprog/close-normal.exp @@ -0,0 +1,3 @@ +(close-normal) begin +(close-normal) end +close-normal: exit(0) diff --git a/grading/userprog/close-stdin.c b/grading/userprog/close-stdin.c new file mode 100644 index 0000000..0ead7f0 --- /dev/null +++ b/grading/userprog/close-stdin.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(close-stdin) begin\n"); + close (0); + printf ("(close-stdin) end\n"); + return 0; +} diff --git a/grading/userprog/close-stdin.exp b/grading/userprog/close-stdin.exp new file mode 100644 index 0000000..093d1df --- /dev/null +++ b/grading/userprog/close-stdin.exp @@ -0,0 +1,3 @@ +(close-stdin) begin +(close-stdin) end +close-stdin: exit(0) diff --git a/grading/userprog/close-stdout.c b/grading/userprog/close-stdout.c new file mode 100644 index 0000000..1c74ce3 --- /dev/null +++ b/grading/userprog/close-stdout.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(close-stdout) begin\n"); + close (1); + printf ("(close-stdout) end\n"); + return 0; +} diff --git a/grading/userprog/close-stdout.exp b/grading/userprog/close-stdout.exp new file mode 100644 index 0000000..8ed30ae --- /dev/null +++ b/grading/userprog/close-stdout.exp @@ -0,0 +1,3 @@ +(close-stdout) begin +(close-stdout) end +close-stdout: exit(0) diff --git a/grading/userprog/close-twice.c b/grading/userprog/close-twice.c new file mode 100644 index 0000000..2514286 --- /dev/null +++ b/grading/userprog/close-twice.c @@ -0,0 +1,16 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(close-twice) begin\n"); + handle = open ("sample.txt"); + if (handle < 2) + printf ("(close-twice) fail: open() returned %d\n", handle); + close (handle); + close (handle); + printf ("(close-twice) end\n"); + return 0; +} diff --git a/grading/userprog/close-twice.exp b/grading/userprog/close-twice.exp new file mode 100644 index 0000000..deb3d32 --- /dev/null +++ b/grading/userprog/close-twice.exp @@ -0,0 +1,6 @@ +(close-twice) begin +(close-twice) end +close-twice: exit(0) +--OR-- +(close-twice) begin +close-twice: exit(-1) diff --git a/grading/userprog/exit.c b/grading/userprog/exit.c new file mode 100644 index 0000000..6be04df --- /dev/null +++ b/grading/userprog/exit.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(exit) begin\n"); + exit (57); + printf ("(exit) fail\n"); + return 0; +} diff --git a/grading/userprog/exit.exp b/grading/userprog/exit.exp new file mode 100644 index 0000000..00e83e8 --- /dev/null +++ b/grading/userprog/exit.exp @@ -0,0 +1,2 @@ +(exit) begin +exit: exit(57) diff --git a/grading/userprog/halt.c b/grading/userprog/halt.c new file mode 100644 index 0000000..e3e4abf --- /dev/null +++ b/grading/userprog/halt.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(halt) begin\n"); + halt (); + printf ("(halt) fail\n"); + return 0; +} diff --git a/grading/userprog/halt.exp b/grading/userprog/halt.exp new file mode 100644 index 0000000..d421b32 --- /dev/null +++ b/grading/userprog/halt.exp @@ -0,0 +1 @@ +(halt) begin diff --git a/grading/userprog/open-bad-ptr.c b/grading/userprog/open-bad-ptr.c new file mode 100644 index 0000000..71bd119 --- /dev/null +++ b/grading/userprog/open-bad-ptr.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(open-bad-ptr) begin\n"); + open ((char *) 0xc0101234); + printf ("(open-bad-ptr) end\n"); + return 0; +} diff --git a/grading/userprog/open-bad-ptr.exp b/grading/userprog/open-bad-ptr.exp new file mode 100644 index 0000000..b0376a3 --- /dev/null +++ b/grading/userprog/open-bad-ptr.exp @@ -0,0 +1,6 @@ +(open-bad-ptr) begin +(open-bad-ptr) end +open-bad-ptr: exit(0) +--OR-- +(open-bad-ptr) begin +open-bad-ptr: exit(-1) diff --git a/grading/userprog/open-boundary.c b/grading/userprog/open-boundary.c new file mode 100644 index 0000000..374d405 --- /dev/null +++ b/grading/userprog/open-boundary.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +static char * +mk_boundary_string (const char *src) +{ + static char dst[8192]; + char *p = dst + (4096 - (uintptr_t) dst % 4096 - strlen (src) / 2); + strlcpy (p, src, 4096); + return p; +} + +int +main (void) +{ + int handle; + + printf ("(open-boundary) begin\n"); + handle = open (mk_boundary_string ("sample.txt")); + if (handle < 2) + printf ("(open-boundary) fail: open() returned %d\n", handle); + printf ("(open-boundary) end\n"); + return 0; +} diff --git a/grading/userprog/open-boundary.exp b/grading/userprog/open-boundary.exp new file mode 100644 index 0000000..bc1d311 --- /dev/null +++ b/grading/userprog/open-boundary.exp @@ -0,0 +1,3 @@ +(open-boundary) begin +(open-boundary) end +open-boundary: exit(0) diff --git a/grading/userprog/open-empty.c b/grading/userprog/open-empty.c new file mode 100644 index 0000000..2529bce --- /dev/null +++ b/grading/userprog/open-empty.c @@ -0,0 +1,14 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(open-empty) begin\n"); + handle = open (""); + if (handle != -1) + printf ("(open-empty) fail: open() returned %d\n", handle); + printf ("(open-empty) end\n"); + return 0; +} diff --git a/grading/userprog/open-empty.exp b/grading/userprog/open-empty.exp new file mode 100644 index 0000000..9944192 --- /dev/null +++ b/grading/userprog/open-empty.exp @@ -0,0 +1,3 @@ +(open-empty) begin +(open-empty) end +open-empty: exit(0) diff --git a/grading/userprog/open-missing.c b/grading/userprog/open-missing.c new file mode 100644 index 0000000..e7a2b84 --- /dev/null +++ b/grading/userprog/open-missing.c @@ -0,0 +1,14 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(open-missing) begin\n"); + handle = open ("no-such-file"); + if (handle != -1) + printf ("(open-missing) fail: open() returned %d\n", handle); + printf ("(open-missing) end\n"); + return 0; +} diff --git a/grading/userprog/open-missing.exp b/grading/userprog/open-missing.exp new file mode 100644 index 0000000..9e52e13 --- /dev/null +++ b/grading/userprog/open-missing.exp @@ -0,0 +1,3 @@ +(open-missing) begin +(open-missing) end +open-missing: exit(0) diff --git a/grading/userprog/open-normal.c b/grading/userprog/open-normal.c new file mode 100644 index 0000000..74dbbf4 --- /dev/null +++ b/grading/userprog/open-normal.c @@ -0,0 +1,14 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(open-normal) begin\n"); + handle = open ("sample.txt"); + if (handle < 2) + printf ("(open-normal) fail: open() returned %d\n", handle); + printf ("(open-normal) end\n"); + return 0; +} diff --git a/grading/userprog/open-normal.exp b/grading/userprog/open-normal.exp new file mode 100644 index 0000000..7087931 --- /dev/null +++ b/grading/userprog/open-normal.exp @@ -0,0 +1,3 @@ +(open-normal) begin +(open-normal) end +open-normal: exit(0) diff --git a/grading/userprog/open-null.c b/grading/userprog/open-null.c new file mode 100644 index 0000000..5d6cc5c --- /dev/null +++ b/grading/userprog/open-null.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (void) +{ + printf ("(open-null) begin\n"); + open (NULL); + printf ("(open-null) end\n"); + return 0; +} diff --git a/grading/userprog/open-null.exp b/grading/userprog/open-null.exp new file mode 100644 index 0000000..fa8dc57 --- /dev/null +++ b/grading/userprog/open-null.exp @@ -0,0 +1,6 @@ +(open-null) begin +(open-null) end +open-null: exit(0) +--OR-- +(open-null) begin +open-null: exit(-1) diff --git a/grading/userprog/open-twice.c b/grading/userprog/open-twice.c new file mode 100644 index 0000000..f029fe5 --- /dev/null +++ b/grading/userprog/open-twice.c @@ -0,0 +1,22 @@ +#include +#include + +int +main (void) +{ + int h1, h2; + printf ("(open-twice) begin\n"); + + h1 = open ("sample.txt"); + if (h1 < 2) + printf ("(open-twice) fail: open() returned %d first time\n", h1); + + h2 = open ("sample.txt"); + if (h2 < 2) + printf ("(open-twice) fail: open() returned %d second time\n", h2); + if (h1 == h2) + printf ("(open-twice) fail: open() returned %d both times\n", h1); + + printf ("(open-twice) end\n"); + return 0; +} diff --git a/grading/userprog/open-twice.exp b/grading/userprog/open-twice.exp new file mode 100644 index 0000000..650c0d3 --- /dev/null +++ b/grading/userprog/open-twice.exp @@ -0,0 +1,3 @@ +(open-twice) begin +(open-twice) end +open-twice: exit(0) diff --git a/grading/userprog/prep-disk b/grading/userprog/prep-disk new file mode 100755 index 0000000..c775a4e --- /dev/null +++ b/grading/userprog/prep-disk @@ -0,0 +1,57 @@ +#! /usr/bin/perl -w + +use strict; +use Getopt::Long; + +my ($pintos) = "pintos"; +my ($os_disk) = "../../src/userprog/build/os.dsk"; +my ($fs_disk); +my ($test); + +GetOptions ("os-disk=s" => \$os_disk, + "fs-disk=s" => \$fs_disk, + "test=s" => \$test, + "help" => sub { usage (0) }) + or die "option parsing failed; use --help for help\n"; + +if (!defined ($test)) { + die "test name expected; use --help for help\n" + if @ARGV != 1; + $test = shift @ARGV; +} elsif (@ARGV != 0) { + die "can't have non-option arg with --test\n"; +} + +$fs_disk = "$test.dsk" if !defined $fs_disk; + +if (! -e $os_disk) { + print STDERR "$os_disk: stat: $!\n"; + print STDERR "perhaps you should `make' in ../../src/userprog?\n"; + exit 1; +} + +our ($formatted) = 0; + +unlink $fs_disk; +xsystem ("$pintos make-disk '$fs_disk' 2"); +put_file ("$test"); +put_file ("sample.txt") + if grep ($_ eq $test, + qw (open-normal open-boundary open-twice + close-normal close-twice + read-normal read-bad-ptr read-boundary read-zero + write-normal write-boundary write-zero)); + +sub put_file { + my ($fn) = @_; + my ($cmd) = "$pintos -v --os-disk='$os_disk' --fs-disk='$fs_disk' put"; + $cmd .= " -f", $formatted = 1 if !$formatted; + $cmd .= " '$fn'"; + xsystem ($cmd); +} + +sub xsystem { + my ($cmd) = @_; + print "$cmd\n"; + system ($cmd) == 0 || die "command failed\n"; +} diff --git a/grading/userprog/read-bad-fd.c b/grading/userprog/read-bad-fd.c new file mode 100644 index 0000000..eb9700d --- /dev/null +++ b/grading/userprog/read-bad-fd.c @@ -0,0 +1,12 @@ +#include +#include + +int +main (void) +{ + char buf; + printf ("(read-bad-fd) begin\n"); + read (0xc0101234, &buf, 1); + printf ("(read-bad-fd) end\n"); + return 0; +} diff --git a/grading/userprog/read-bad-fd.exp b/grading/userprog/read-bad-fd.exp new file mode 100644 index 0000000..0c30c9a --- /dev/null +++ b/grading/userprog/read-bad-fd.exp @@ -0,0 +1,6 @@ +(read-bad-fd) begin +(read-bad-fd) end +read-bad-fd: exit(0) +--OR-- +(read-bad-fd) begin +read-bad-fd: exit(-1) diff --git a/grading/userprog/read-bad-ptr.c b/grading/userprog/read-bad-ptr.c new file mode 100644 index 0000000..860e485 --- /dev/null +++ b/grading/userprog/read-bad-ptr.c @@ -0,0 +1,18 @@ +#include +#include + +int +main (void) +{ + int handle; + printf ("(read-bad-ptr) begin\n"); + + handle = open ("sample.txt"); + if (handle < 2) + printf ("(read-bad-ptr) fail: open() returned %d\n", handle); + + read (handle, (char *) 0xc0101234, 123); + + printf ("(read-bad-ptr) end\n"); + return 0; +} diff --git a/grading/userprog/read-bad-ptr.exp b/grading/userprog/read-bad-ptr.exp new file mode 100644 index 0000000..fe4d3ed --- /dev/null +++ b/grading/userprog/read-bad-ptr.exp @@ -0,0 +1,6 @@ +(read-bad-ptr) begin +(read-bad-ptr) end +read-bad-ptr: exit(0) +--OR-- +(read-bad-ptr) begin +read-bad-ptr: exit(-1) diff --git a/grading/userprog/read-boundary.c b/grading/userprog/read-boundary.c new file mode 100644 index 0000000..7992730 --- /dev/null +++ b/grading/userprog/read-boundary.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include + +char expected[] = { + "Amazing Electronic Fact: If you scuffed your feet long enough without\n" + "touching anything, you would build up so many electrons that your\n" + "finger would explode! But this is nothing to worry about unless you\n" + "have carpeting.\n" +}; + + + +static char * +mk_boundary_string (const char *src) +{ + static char dst[8192]; + char *p = dst + (4096 - (uintptr_t) dst % 4096 - strlen (src) / 2); + strlcpy (p, src, 4096); + return p; +} + +int +main (void) +{ + int handle; + int byte_cnt; + char *actual_p; + + actual_p = mk_boundary_string (expected); + + printf ("(read-boundary) begin\n"); + + handle = open ("sample.txt"); + if (handle < 2) + printf ("(read-boundary) fail: open() returned %d\n", handle); + + byte_cnt = read (handle, actual_p, sizeof expected - 1); + if (byte_cnt != sizeof expected - 1) + printf ("(read-boundary) fail: read() returned %d instead of %d\n", + byte_cnt, sizeof expected - 1); + else if (strcmp (expected, actual_p)) + printf ("(read-boundary) fail: expected text differs from actual:\n%s", + actual_p); + + printf ("(read-boundary) end\n"); + return 0; +} diff --git a/grading/userprog/read-boundary.exp b/grading/userprog/read-boundary.exp new file mode 100644 index 0000000..cbbcda8 --- /dev/null +++ b/grading/userprog/read-boundary.exp @@ -0,0 +1,3 @@ +(read-boundary) begin +(read-boundary) end +read-boundary: exit(0) diff --git a/grading/userprog/read-normal.c b/grading/userprog/read-normal.c new file mode 100644 index 0000000..4bb7679 --- /dev/null +++ b/grading/userprog/read-normal.c @@ -0,0 +1,34 @@ +#include +#include +#include + +char expected[] = { + "Amazing Electronic Fact: If you scuffed your feet long enough without\n" + "touching anything, you would build up so many electrons that your\n" + "finger would explode! But this is nothing to worry about unless you\n" + "have carpeting.\n" +}; + +char actual[sizeof expected]; + +int +main (void) +{ + int handle, byte_cnt; + printf ("(read-normal) begin\n"); + + handle = open ("sample.txt"); + if (handle < 2) + printf ("(read-normal) fail: open() returned %d\n", handle); + + byte_cnt = read (handle, actual, sizeof actual - 1); + if (byte_cnt != sizeof actual - 1) + printf ("(read-normal) fail: read() returned %d instead of %d\n", + byte_cnt, sizeof actual - 1); + else if (strcmp (expected, actual)) + printf ("(read-normal) fail: expected text differs from actual:\n%s", + actual); + + printf ("(read-normal) end\n"); + return 0; +} diff --git a/grading/userprog/read-normal.exp b/grading/userprog/read-normal.exp new file mode 100644 index 0000000..e45dc51 --- /dev/null +++ b/grading/userprog/read-normal.exp @@ -0,0 +1,3 @@ +(read-normal) begin +(read-normal) end +read-normal: exit(0) diff --git a/grading/userprog/read-stdout.c b/grading/userprog/read-stdout.c new file mode 100644 index 0000000..df0274c --- /dev/null +++ b/grading/userprog/read-stdout.c @@ -0,0 +1,12 @@ +#include +#include + +int +main (void) +{ + char buf; + printf ("(read-stdout) begin\n"); + read (1, &buf, 1); + printf ("(read-stdout) end\n"); + return 0; +} diff --git a/grading/userprog/read-stdout.exp b/grading/userprog/read-stdout.exp new file mode 100644 index 0000000..63c1d52 --- /dev/null +++ b/grading/userprog/read-stdout.exp @@ -0,0 +1,6 @@ +(read-stdout) begin +(read-stdout) end +read-stdout: exit(0) +--OR-- +(read-stdout) begin +read-stdout: exit(-1) diff --git a/grading/userprog/read-zero.c b/grading/userprog/read-zero.c new file mode 100644 index 0000000..7f9ec82 --- /dev/null +++ b/grading/userprog/read-zero.c @@ -0,0 +1,24 @@ +#include +#include + +int +main (void) +{ + int handle, byte_cnt; + char buf; + printf ("(read-zero) begin\n"); + + handle = open ("sample.txt"); + if (handle < 2) + printf ("(read-zero) fail: open() returned %d\n", handle); + + buf = 123; + byte_cnt = read (handle, &buf, 0); + if (byte_cnt != 0) + printf ("(read-zero) fail: read() returned %d instead of 0\n", byte_cnt); + else if (buf != 123) + printf ("(read-zero) fail: 0-byte read() modified buffer\n"); + + printf ("(read-zero) end\n"); + return 0; +} diff --git a/grading/userprog/read-zero.exp b/grading/userprog/read-zero.exp new file mode 100644 index 0000000..f1b438a --- /dev/null +++ b/grading/userprog/read-zero.exp @@ -0,0 +1,3 @@ +(read-zero) begin +(read-zero) end +read-zero: exit(0) diff --git a/grading/userprog/run-tests b/grading/userprog/run-tests index e7a31ac..3781649 100755 --- a/grading/userprog/run-tests +++ b/grading/userprog/run-tests @@ -37,11 +37,18 @@ sub usage { } # Default set of tests. -@TESTS = qw (create-normal create-empty create-null create-bad-ptr +@TESTS = qw (args-argc args-argv0 args-argvn args-single args-multiple + args-dbl-space + sc-bad-sp sc-bad-arg sc-boundary + halt exit + create-normal create-empty create-null create-bad-ptr create-long create-exists create-bound - args-argc args-argv0 args-argvn args-single args-multiple - args-dbl-space) - unless @TESTS > 0; + open-normal open-missing open-boundary open-empty open-null + open-bad-ptr open-twice + close-normal close-twice close-stdin close-stdout close-bad-fd + read-normal read-bad-ptr read-boundary read-zero read-stdout + read-bad-fd + ) unless @TESTS > 0; our (%args); for my $key ('args-argc', 'args-argv0', 'args-argvn', 'args-multiple') { @@ -623,7 +630,7 @@ sub compare_output { # They differ. Output a diff. my (@diff) = ""; my ($d) = Algorithm::Diff->new (\@expected, \@actual); - my ($all_additions) = 1; + my ($not_fuzzy_match) = 0; while ($d->Next ()) { my ($ef, $el, $af, $al) = $d->Get (qw (min1 max1 min2 max2)); if ($d->Same ()) { @@ -631,11 +638,13 @@ sub compare_output { } else { push (@diff, map ("- $_", $d->Items (1))) if $d->Items (1); push (@diff, map ("+ $_", $d->Items (2))) if $d->Items (2); - $all_additions = 0 if $d->Items (1); + if ($d->Items (1) + || grep (/\($test\)|exit\(-?\d+\)/, $d->Items (2))) { + $not_fuzzy_match = 1; + } } } - - $fuzzy_match = 1 if $all_additions; + $fuzzy_match = 1 if !$not_fuzzy_match; $details .= "Differences in `diff -u' format:\n"; $details .= join ('', @diff); diff --git a/grading/userprog/sample.txt b/grading/userprog/sample.txt new file mode 100644 index 0000000..9e0dd45 --- /dev/null +++ b/grading/userprog/sample.txt @@ -0,0 +1,4 @@ +Amazing Electronic Fact: If you scuffed your feet long enough without +touching anything, you would build up so many electrons that your +finger would explode! But this is nothing to worry about unless you +have carpeting. diff --git a/grading/userprog/sc-bad-arg.c b/grading/userprog/sc-bad-arg.c index 8bbd8ea..e6019a6 100644 --- a/grading/userprog/sc-bad-arg.c +++ b/grading/userprog/sc-bad-arg.c @@ -5,7 +5,7 @@ int main (void) { printf ("(sc-bad-arg) begin\n"); - asm volatile ("mov $0xbffffffc, %%esp; movl $%0, (%%esp); int $0x30" + asm volatile ("mov $0xbffffffc, %%esp; movl %0, (%%esp); int $0x30" : : "i" (SYS_exit)); printf ("(sc-bad-arg) end\n"); diff --git a/grading/userprog/sc-bad-sp.c b/grading/userprog/sc-bad-sp.c index 9d996e9..d7a0f82 100644 --- a/grading/userprog/sc-bad-sp.c +++ b/grading/userprog/sc-bad-sp.c @@ -5,7 +5,7 @@ int main (void) { printf ("(sc-bad-sp) begin\n"); - asm volatile ("mov $0xc0101234, %%esp; int $0x30"); + asm volatile ("mov $0xc0101234, %esp; int $0x30"); printf ("(sc-bad-sp) end\n"); return 0; } diff --git a/grading/userprog/sc-boundary.c b/grading/userprog/sc-boundary.c new file mode 100644 index 0000000..401e437 --- /dev/null +++ b/grading/userprog/sc-boundary.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +static void * +mk_boundary_array (void) +{ + static char dst[8192]; + return dst + (4096 - (uintptr_t) dst % 4096); +} + +int +main (void) +{ + int *p; + + printf ("(sc-boundary) begin\n"); + p = mk_boundary_array (); + p--; + p[0] = SYS_exit; + p[1] = 42; + asm volatile ("mov %0, %%esp; int $0x30" + : + : "g" (p)); + printf ("(sc-boundary) failed\n"); + return 1; +} diff --git a/grading/userprog/sc-boundary.exp b/grading/userprog/sc-boundary.exp new file mode 100644 index 0000000..1f38d87 --- /dev/null +++ b/grading/userprog/sc-boundary.exp @@ -0,0 +1,2 @@ +(sc-boundary) begin +sc-boundary: exit(42) diff --git a/grading/userprog/tests.txt b/grading/userprog/tests.txt index 73027a4..ce7c393 100644 --- a/grading/userprog/tests.txt +++ b/grading/userprog/tests.txt @@ -37,8 +37,9 @@ System calls: open -2 open-boundary: pass name of file crossing page boundary -1 open-empty: pass empty string to open system call -1 open-null: pass null pointer to open system call + -1 open-bad-ptr: pass invalid pointer to open system call -1 open-twice: open the same file twice -Score: /9 +Score: /10 System calls: close -2 close-normal: close an open file in the most normal way diff --git a/src/Makefile.userprog b/src/Makefile.userprog index 6b3c250..4cdf078 100644 --- a/src/Makefile.userprog +++ b/src/Makefile.userprog @@ -27,18 +27,19 @@ LIB_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(LIB_SRC))) LIB_DEP = $(patsubst %.o,%.d,$(LIB_OBJ)) LIB = lib/user/entry.o libc.a -PROGS_SRC = $(foreach prog,$(PROGS),$($(prog)_SRC)) +PROGS_SRC = $(foreach prog,$(PROGS),$($(subst -,_,$(prog))_SRC)) PROGS_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(PROGS_SRC))) PROGS_DEP = $(patsubst %.o,%.d,$(PROGS_OBJ)) all: $(PROGS) define TEMPLATE -$(1)_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$($(1)_SRC))) -$(1): $$($(1)_OBJ) $$(LIB) +$(2)_OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$($(2)_SRC))) +$(1): $$($(2)_OBJ) $$(LIB) + $$(CC) $$(LDFLAGS) $$^ $$(LDLIBS) -o $$@ endef -$(foreach prog,$(PROGS),$(eval $(call TEMPLATE,$(prog)))) +$(foreach prog,$(PROGS),$(eval $(call TEMPLATE,$(prog),$(subst -,_,$(prog))))) $(PROGS): $(LIB) diff --git a/src/utils/pintos b/src/utils/pintos index 6bb9f09..798708e 100755 --- a/src/utils/pintos +++ b/src/utils/pintos @@ -11,15 +11,27 @@ our ($vga); our ($jitter); use Getopt::Long qw(:config require_order bundling); -GetOptions ("bochs|qemu|gsx" => \&set_sim, - "no-debug|monitor|gdb" => \&set_debug, +GetOptions ("sim=s" => sub { set_sim (@_) }, + "bochs" => sub { set_sim ("bochs") }, + "qemu" => sub { set_sim ("qemu") }, + "gsx" => sub { set_sim ("gsx") }, + + "debug=s" => sub { set_debug (@_) }, + "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" => \$jitter, + "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], "1|fs-disk|disk-1|hdb=s" => \$disks[1], "2|scratch-disk|disk-2|hdc=s" => \$disks[2], @@ -31,15 +43,17 @@ $debug = "no-debug" if !defined $debug; $vga = "window" if !defined $vga; sub set_sim { - my ($option) = @_; - die "--$option conflicts with --$sim\n" if defined $sim; - our ($sim) = $option; + my ($new_sim) = @_; + die "--$new_sim conflicts with --$sim\n" + if defined ($sim) && $sim ne $new_sim; + $sim = $new_sim; } sub set_debug { - my ($option) = @_; - die "--$option conflicts with --$debug\n" if defined $debug; - our ($debug) = $option; + my ($new_debug) = @_; + die "--$new_debug conflicts with --$debug\n" + if defined ($debug) && $debug ne $new_debug; + $debug = $new_debug; } sub set_vga { @@ -47,12 +61,10 @@ sub set_vga { if (defined ($vga) && $vga ne $new_vga) { print "warning: conflicting vga display options\n"; } - our ($vga) = $new_vga; + $vga = $new_vga; } sub cmd_option { - our ($cmd) = @_; - # Force an end to option processing, as with --. die ("!FINISH"); } @@ -70,6 +82,13 @@ if ($cmd eq 'run') { create_disk ($file, int ($mb * 1008)); } elsif ($cmd eq 'put') { + # Take a -f option to combine formatting with putting. + my ($format) = 0; + if (@ARGV > 0 && $ARGV[0] eq '-f') { + shift @ARGV; + $format = 1; + } + usage () if @ARGV != 1 && @ARGV != 2; my ($hostfn, $guestfn) = @ARGV; $guestfn = $hostfn if !defined $guestfn; @@ -80,7 +99,9 @@ if ($cmd eq 'run') { copy_pad ($hostfn, "scratch.dsk", 512); # Do copy. - run_vm ("-ci", $guestfn, $size, "-q"); + my (@cmd) = ("-ci", $guestfn, $size, "-q"); + unshift (@cmd, "-f") if $format; + run_vm (@cmd); } elsif ($cmd eq 'get') { usage () if @ARGV != 1 && @ARGV != 2; my ($guestfn, $hostfn) = @ARGV;