Add more tests.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 1 Nov 2004 05:33:30 +0000 (05:33 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 1 Nov 2004 05:33:30 +0000 (05:33 +0000)
Fix - in makefile var bug reported by Jim.
Make pintos util able to format and put in one step.

52 files changed:
grading/userprog/.cvsignore
grading/userprog/Makefile
grading/userprog/close-bad-fd.c [new file with mode: 0644]
grading/userprog/close-bad-fd.exp [new file with mode: 0644]
grading/userprog/close-normal.c [new file with mode: 0644]
grading/userprog/close-normal.exp [new file with mode: 0644]
grading/userprog/close-stdin.c [new file with mode: 0644]
grading/userprog/close-stdin.exp [new file with mode: 0644]
grading/userprog/close-stdout.c [new file with mode: 0644]
grading/userprog/close-stdout.exp [new file with mode: 0644]
grading/userprog/close-twice.c [new file with mode: 0644]
grading/userprog/close-twice.exp [new file with mode: 0644]
grading/userprog/exit.c [new file with mode: 0644]
grading/userprog/exit.exp [new file with mode: 0644]
grading/userprog/halt.c [new file with mode: 0644]
grading/userprog/halt.exp [new file with mode: 0644]
grading/userprog/open-bad-ptr.c [new file with mode: 0644]
grading/userprog/open-bad-ptr.exp [new file with mode: 0644]
grading/userprog/open-boundary.c [new file with mode: 0644]
grading/userprog/open-boundary.exp [new file with mode: 0644]
grading/userprog/open-empty.c [new file with mode: 0644]
grading/userprog/open-empty.exp [new file with mode: 0644]
grading/userprog/open-missing.c [new file with mode: 0644]
grading/userprog/open-missing.exp [new file with mode: 0644]
grading/userprog/open-normal.c [new file with mode: 0644]
grading/userprog/open-normal.exp [new file with mode: 0644]
grading/userprog/open-null.c [new file with mode: 0644]
grading/userprog/open-null.exp [new file with mode: 0644]
grading/userprog/open-twice.c [new file with mode: 0644]
grading/userprog/open-twice.exp [new file with mode: 0644]
grading/userprog/prep-disk [new file with mode: 0755]
grading/userprog/read-bad-fd.c [new file with mode: 0644]
grading/userprog/read-bad-fd.exp [new file with mode: 0644]
grading/userprog/read-bad-ptr.c [new file with mode: 0644]
grading/userprog/read-bad-ptr.exp [new file with mode: 0644]
grading/userprog/read-boundary.c [new file with mode: 0644]
grading/userprog/read-boundary.exp [new file with mode: 0644]
grading/userprog/read-normal.c [new file with mode: 0644]
grading/userprog/read-normal.exp [new file with mode: 0644]
grading/userprog/read-stdout.c [new file with mode: 0644]
grading/userprog/read-stdout.exp [new file with mode: 0644]
grading/userprog/read-zero.c [new file with mode: 0644]
grading/userprog/read-zero.exp [new file with mode: 0644]
grading/userprog/run-tests
grading/userprog/sample.txt [new file with mode: 0644]
grading/userprog/sc-bad-arg.c
grading/userprog/sc-bad-sp.c
grading/userprog/sc-boundary.c [new file with mode: 0644]
grading/userprog/sc-boundary.exp [new file with mode: 0644]
grading/userprog/tests.txt
src/Makefile.userprog
src/utils/pintos

index a4383358ec72fb4d15f30791cb5265a6e06c5416..73d1273bd0d8c68e382a1564159f942a19d67e87 100644 (file)
@@ -1 +1,2 @@
 *.d
+*.dsk
index 25ba85759b7e0bbfab6354f8f4eb72adbd67950b..e95e13fdaf032568be18041a61059077f0ed6d03 100644 (file)
@@ -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 (file)
index 0000000..cdea3c5
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..5ac59da
--- /dev/null
@@ -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 (file)
index 0000000..2b5e95d
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..f3be9bc
--- /dev/null
@@ -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 (file)
index 0000000..0ead7f0
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..093d1df
--- /dev/null
@@ -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 (file)
index 0000000..1c74ce3
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..8ed30ae
--- /dev/null
@@ -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 (file)
index 0000000..2514286
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..deb3d32
--- /dev/null
@@ -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 (file)
index 0000000..6be04df
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..00e83e8
--- /dev/null
@@ -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 (file)
index 0000000..e3e4abf
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..d421b32
--- /dev/null
@@ -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 (file)
index 0000000..71bd119
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..b0376a3
--- /dev/null
@@ -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 (file)
index 0000000..374d405
--- /dev/null
@@ -0,0 +1,26 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..bc1d311
--- /dev/null
@@ -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 (file)
index 0000000..2529bce
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..9944192
--- /dev/null
@@ -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 (file)
index 0000000..e7a2b84
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..9e52e13
--- /dev/null
@@ -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 (file)
index 0000000..74dbbf4
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..7087931
--- /dev/null
@@ -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 (file)
index 0000000..5d6cc5c
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..fa8dc57
--- /dev/null
@@ -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 (file)
index 0000000..f029fe5
--- /dev/null
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..650c0d3
--- /dev/null
@@ -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 (executable)
index 0000000..c775a4e
--- /dev/null
@@ -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 (file)
index 0000000..eb9700d
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..0c30c9a
--- /dev/null
@@ -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 (file)
index 0000000..860e485
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..fe4d3ed
--- /dev/null
@@ -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 (file)
index 0000000..7992730
--- /dev/null
@@ -0,0 +1,49 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..cbbcda8
--- /dev/null
@@ -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 (file)
index 0000000..4bb7679
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..e45dc51
--- /dev/null
@@ -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 (file)
index 0000000..df0274c
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..63c1d52
--- /dev/null
@@ -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 (file)
index 0000000..7f9ec82
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <syscall.h>
+
+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 (file)
index 0000000..f1b438a
--- /dev/null
@@ -0,0 +1,3 @@
+(read-zero) begin
+(read-zero) end
+read-zero: exit(0)
index e7a31acb5f06190369f9329b880a4e5623282da8..37816499814230bb9aceba85fc9721b1e3d8acc4 100755 (executable)
@@ -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 (file)
index 0000000..9e0dd45
--- /dev/null
@@ -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.
index 8bbd8eab7b36754acfd738bd71aa31026b04ec81..e6019a69fd790e595f984c9ed2d35b8c72cee616 100644 (file)
@@ -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"); 
index 9d996e980a248eab143dc78718d24fa2ffae4c9a..d7a0f826a17b747828b3d1f62a8d0dc94091b734 100644 (file)
@@ -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 (file)
index 0000000..401e437
--- /dev/null
@@ -0,0 +1,28 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <syscall-nr.h>
+
+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 (file)
index 0000000..1f38d87
--- /dev/null
@@ -0,0 +1,2 @@
+(sc-boundary) begin
+sc-boundary: exit(42)
index 73027a4083e496d22dac61ea0da26899c580109e..ce7c3931b11452af1167fe56820cdea311f09b73 100644 (file)
@@ -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
index 6b3c25027d2df1445ee00472292f17d619b044e3..4cdf078ab9898f36ccbdec5835692b7a8c1c71b4 100644 (file)
@@ -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)
 
index 6bb9f09824f416f5187009da97ad6acb55cb9c2b..798708ed912dd73a728773e66b0ec6ed477c707b 100755 (executable)
@@ -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;