$(addprefix write-, normal bad-ptr boundary zero stdin bad-fd) \
$(addprefix exec-, once arg multiple missing bad-ptr) \
$(addprefix join-, simple twice killed bad-pid) \
- $(addprefix multi-, recurse oom)
+ $(addprefix multi-, recurse oom child-fd)
define TEST_PROG
PROGS += $(1)
disks: $(DISKS)
# Other programs needed by some of the main test programs.
-PROGS += child-simple child-arg child-bad
+PROGS += child-simple child-arg child-bad child-close
child_simple_SRC = child-simple.c
child_arg_SRC = child-arg.c
child_bad_SRC = child-bad.c
+child_close_SRC = child-close.c
exec-once.dsk exec-multiple.dsk join-simple.dsk join-twice.dsk: child-simple
exec-arg.dsk: child-arg
join-killed.dsk: child-bad
+multi-child-fd.dsk: child-close
%.dsk: %
./prep-disk $<
--- /dev/null
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syscall.h>
+
+int
+main (int argc UNUSED, char *argv[])
+{
+ if (isdigit (*argv[0]))
+ close (atoi (argv[0]));
+ else if (isdigit (*argv[1]))
+ close (atoi (argv[1]));
+ else
+ {
+ printf ("(child-close) fail: bad command-line arguments\n");
+ return 1;
+ }
+ printf ("(child-close) success\n");
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+#include "sample.inc"
+
+char actual[sizeof sample];
+
+int
+main (void)
+{
+ char child_cmd[128];
+ int byte_cnt;
+ int handle;
+
+ printf ("(multi-child-fd) begin\n");
+
+ handle = open("sample.txt");
+ if (handle < 2)
+ printf ("(multi-child-fd) fail: open() returned %d\n", handle);
+
+ snprintf (child_cmd, sizeof child_cmd, "child-close %d", handle);
+
+ printf ("(multi-child-fd) join(exec()) = %d\n", join (exec (child_cmd)));
+
+ byte_cnt = read (handle, actual, sizeof actual - 1);
+ if (byte_cnt != sizeof actual - 1)
+ printf ("(multi-child-fd) fail: read() returned %d instead of %d\n",
+ byte_cnt, sizeof actual - 1);
+ else if (strcmp (sample, actual))
+ printf ("(multi-child-fd) fail: expected text differs from actual:\n%s",
+ actual);
+
+ printf ("(multi-child-fd) end\n");
+ return 0;
+}
--- /dev/null
+(multi-child-fd) begin
+(child-close) success
+child-close: exit(0)
+(multi-child-fd) join(exec()) = 0
+(multi-child-fd) end
+multi-child-fd: exit(0)
+--OR--
+(multi-child-fd) begin
+child-close: exit(-1)
+(multi-child-fd) join(exec()) = -1
+(multi-child-fd) end
+multi-child-fd: exit(0)
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+#include "sample.inc"
+
+char actual[sizeof sample];
+
+int
+main (void)
+{
+ char child_cmd[128];
+ int byte_cnt;
+ int handle;
+
+ printf ("(multi-child-fd) begin\n");
+
+ handle = open("sample.txt");
+ if (handle < 2)
+ printf ("(multi-child-fd) fail: open() returned %d\n", handle);
+
+ snprintf (child_cmd, sizeof child_cmd, "child-close %d", handle);
+
+ printf ("(multi-child-fd) join(exec()) = %d\n", join (exec (child_cmd)));
+
+ byte_cnt = read (handle, actual, sizeof actual - 1);
+ if (byte_cnt != sizeof actual - 1)
+ printf ("(multi-child-fd) fail: read() returned %d instead of %d\n",
+ byte_cnt, sizeof actual - 1);
+ else if (strcmp (sample, actual))
+ printf ("(multi-child-fd) fail: expected text differs from actual:\n%s",
+ actual);
+
+ printf ("(multi-child-fd) end\n");
+ return 0;
+}
qw (open-normal open-boundary open-twice
close-normal close-twice
read-normal read-bad-ptr read-boundary read-zero
- write-normal write-bad-ptr write-boundary write-zero));
+ write-normal write-bad-ptr write-boundary write-zero
+ multi-child-fd));
put_file ("child-simple") if $test eq 'exec-once' or $test eq 'exec-multiple';
put_file ("child-arg") if $test eq 'exec-arg';
+put_file ("child-close") if $test eq 'multi-child-fd';
sub put_file {
my ($fn) = @_;
write-normal write-bad-ptr write-boundary write-zero write-stdin
write-bad-fd
exec-once exec-arg exec-multiple exec-missing exec-bad-ptr
- multi-recurse multi-oom
+ multi-recurse multi-oom multi-child-fd
) unless @TESTS > 0;
our (%args);
xsystem ("patch -fs pintos/src/lib/debug.c < $GRADES_DIR/panic.diff",
LOG => "patch",
DIE => "patch failed\n");
+ xsystem ("patch -fs pintos/src/lib/kernel/bitmap.c "
+ . "< $GRADES_DIR/random.diff",
+ LOG => "patch",
+ DIE => "patch failed\n");
+
+ open (CONSTANTS, ">pintos/src/constants.h")
+ or die "constants.h: create: $!\n";
+ print CONSTANTS "#define THREAD_JOIN_IMPLEMENTED 1\n";
+ close CONSTANTS;
}
sub ext_mdyHMS {
} else {
$A2L = "i386-elf-addr2line";
}
- open (A2L, "$A2L -fe output/$test/kernel.o @addrs|");
+ open (A2L, "$A2L -fe pintos/src/userprog/build/kernel.o @addrs|");
for (;;) {
my ($function, $line);
last unless defined ($function = <A2L>);