diff options
Diffstat (limited to 'pintos-progos/tests/userprog')
140 files changed, 2421 insertions, 0 deletions
diff --git a/pintos-progos/tests/userprog/Make.tests b/pintos-progos/tests/userprog/Make.tests new file mode 100644 index 0000000..88b0737 --- /dev/null +++ b/pintos-progos/tests/userprog/Make.tests | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | # -*- makefile -*- | ||
| 2 | |||
| 3 | tests/%.output: FILESYSSOURCE = --filesys-size=2 | ||
| 4 | tests/%.output: PUTFILES = $(filter-out kernel.bin loader.bin, $^) | ||
| 5 | |||
| 6 | tests/userprog_TESTS = $(addprefix tests/userprog/,args-none \ | ||
| 7 | args-single args-multiple args-many args-dbl-space sc-bad-sp \ | ||
| 8 | sc-bad-arg sc-boundary sc-boundary-2 halt exit create-normal \ | ||
| 9 | create-empty create-null create-bad-ptr create-long create-exists \ | ||
| 10 | create-bound open-normal open-missing open-boundary open-empty \ | ||
| 11 | open-null open-bad-ptr open-twice close-normal close-twice close-stdin \ | ||
| 12 | close-stdout close-bad-fd read-normal read-bad-ptr read-boundary \ | ||
| 13 | read-zero read-stdout read-bad-fd write-normal write-bad-ptr \ | ||
| 14 | write-boundary write-zero write-stdin write-bad-fd exec-once exec-arg \ | ||
| 15 | exec-multiple exec-missing exec-bad-ptr wait-simple wait-twice \ | ||
| 16 | wait-killed wait-bad-pid multi-recurse multi-child-fd rox-simple \ | ||
| 17 | rox-child rox-multichild bad-read bad-write bad-read2 bad-write2 \ | ||
| 18 | bad-jump bad-jump2) | ||
| 19 | |||
| 20 | tests/userprog_PROGS = $(tests/userprog_TESTS) $(addprefix \ | ||
| 21 | tests/userprog/,child-simple child-args child-bad child-close child-rox) | ||
| 22 | |||
| 23 | tests/userprog/args-none_SRC = tests/userprog/args.c | ||
| 24 | tests/userprog/args-single_SRC = tests/userprog/args.c | ||
| 25 | tests/userprog/args-multiple_SRC = tests/userprog/args.c | ||
| 26 | tests/userprog/args-many_SRC = tests/userprog/args.c | ||
| 27 | tests/userprog/args-dbl-space_SRC = tests/userprog/args.c | ||
| 28 | tests/userprog/sc-bad-sp_SRC = tests/userprog/sc-bad-sp.c tests/main.c | ||
| 29 | tests/userprog/sc-bad-arg_SRC = tests/userprog/sc-bad-arg.c tests/main.c | ||
| 30 | tests/userprog/bad-read_SRC = tests/userprog/bad-read.c tests/main.c | ||
| 31 | tests/userprog/bad-write_SRC = tests/userprog/bad-write.c tests/main.c | ||
| 32 | tests/userprog/bad-jump_SRC = tests/userprog/bad-jump.c tests/main.c | ||
| 33 | tests/userprog/bad-read2_SRC = tests/userprog/bad-read2.c tests/main.c | ||
| 34 | tests/userprog/bad-write2_SRC = tests/userprog/bad-write2.c tests/main.c | ||
| 35 | tests/userprog/bad-jump2_SRC = tests/userprog/bad-jump2.c tests/main.c | ||
| 36 | tests/userprog/sc-boundary_SRC = tests/userprog/sc-boundary.c \ | ||
| 37 | tests/userprog/boundary.c tests/main.c | ||
| 38 | tests/userprog/sc-boundary-2_SRC = tests/userprog/sc-boundary-2.c \ | ||
| 39 | tests/userprog/boundary.c tests/main.c | ||
| 40 | tests/userprog/halt_SRC = tests/userprog/halt.c tests/main.c | ||
| 41 | tests/userprog/exit_SRC = tests/userprog/exit.c tests/main.c | ||
| 42 | tests/userprog/create-normal_SRC = tests/userprog/create-normal.c tests/main.c | ||
| 43 | tests/userprog/create-empty_SRC = tests/userprog/create-empty.c tests/main.c | ||
| 44 | tests/userprog/create-null_SRC = tests/userprog/create-null.c tests/main.c | ||
| 45 | tests/userprog/create-bad-ptr_SRC = tests/userprog/create-bad-ptr.c \ | ||
| 46 | tests/main.c | ||
| 47 | tests/userprog/create-long_SRC = tests/userprog/create-long.c tests/main.c | ||
| 48 | tests/userprog/create-exists_SRC = tests/userprog/create-exists.c tests/main.c | ||
| 49 | tests/userprog/create-bound_SRC = tests/userprog/create-bound.c \ | ||
| 50 | tests/userprog/boundary.c tests/main.c | ||
| 51 | tests/userprog/open-normal_SRC = tests/userprog/open-normal.c tests/main.c | ||
| 52 | tests/userprog/open-missing_SRC = tests/userprog/open-missing.c tests/main.c | ||
| 53 | tests/userprog/open-boundary_SRC = tests/userprog/open-boundary.c \ | ||
| 54 | tests/userprog/boundary.c tests/main.c | ||
| 55 | tests/userprog/open-empty_SRC = tests/userprog/open-empty.c tests/main.c | ||
| 56 | tests/userprog/open-null_SRC = tests/userprog/open-null.c tests/main.c | ||
| 57 | tests/userprog/open-bad-ptr_SRC = tests/userprog/open-bad-ptr.c tests/main.c | ||
| 58 | tests/userprog/open-twice_SRC = tests/userprog/open-twice.c tests/main.c | ||
| 59 | tests/userprog/close-normal_SRC = tests/userprog/close-normal.c tests/main.c | ||
| 60 | tests/userprog/close-twice_SRC = tests/userprog/close-twice.c tests/main.c | ||
| 61 | tests/userprog/close-stdin_SRC = tests/userprog/close-stdin.c tests/main.c | ||
| 62 | tests/userprog/close-stdout_SRC = tests/userprog/close-stdout.c tests/main.c | ||
| 63 | tests/userprog/close-bad-fd_SRC = tests/userprog/close-bad-fd.c tests/main.c | ||
| 64 | tests/userprog/read-normal_SRC = tests/userprog/read-normal.c tests/main.c | ||
| 65 | tests/userprog/read-bad-ptr_SRC = tests/userprog/read-bad-ptr.c tests/main.c | ||
| 66 | tests/userprog/read-boundary_SRC = tests/userprog/read-boundary.c \ | ||
| 67 | tests/userprog/boundary.c tests/main.c | ||
| 68 | tests/userprog/read-zero_SRC = tests/userprog/read-zero.c tests/main.c | ||
| 69 | tests/userprog/read-stdout_SRC = tests/userprog/read-stdout.c tests/main.c | ||
| 70 | tests/userprog/read-bad-fd_SRC = tests/userprog/read-bad-fd.c tests/main.c | ||
| 71 | tests/userprog/write-normal_SRC = tests/userprog/write-normal.c tests/main.c | ||
| 72 | tests/userprog/write-bad-ptr_SRC = tests/userprog/write-bad-ptr.c tests/main.c | ||
| 73 | tests/userprog/write-boundary_SRC = tests/userprog/write-boundary.c \ | ||
| 74 | tests/userprog/boundary.c tests/main.c | ||
| 75 | tests/userprog/write-zero_SRC = tests/userprog/write-zero.c tests/main.c | ||
| 76 | tests/userprog/write-stdin_SRC = tests/userprog/write-stdin.c tests/main.c | ||
| 77 | tests/userprog/write-bad-fd_SRC = tests/userprog/write-bad-fd.c tests/main.c | ||
| 78 | tests/userprog/exec-once_SRC = tests/userprog/exec-once.c tests/main.c | ||
| 79 | tests/userprog/exec-arg_SRC = tests/userprog/exec-arg.c tests/main.c | ||
| 80 | tests/userprog/exec-multiple_SRC = tests/userprog/exec-multiple.c tests/main.c | ||
| 81 | tests/userprog/exec-missing_SRC = tests/userprog/exec-missing.c tests/main.c | ||
| 82 | tests/userprog/exec-bad-ptr_SRC = tests/userprog/exec-bad-ptr.c tests/main.c | ||
| 83 | tests/userprog/wait-simple_SRC = tests/userprog/wait-simple.c tests/main.c | ||
| 84 | tests/userprog/wait-twice_SRC = tests/userprog/wait-twice.c tests/main.c | ||
| 85 | tests/userprog/wait-killed_SRC = tests/userprog/wait-killed.c tests/main.c | ||
| 86 | tests/userprog/wait-bad-pid_SRC = tests/userprog/wait-bad-pid.c tests/main.c | ||
| 87 | tests/userprog/multi-recurse_SRC = tests/userprog/multi-recurse.c | ||
| 88 | tests/userprog/multi-child-fd_SRC = tests/userprog/multi-child-fd.c \ | ||
| 89 | tests/main.c | ||
| 90 | tests/userprog/rox-simple_SRC = tests/userprog/rox-simple.c tests/main.c | ||
| 91 | tests/userprog/rox-child_SRC = tests/userprog/rox-child.c tests/main.c | ||
| 92 | tests/userprog/rox-multichild_SRC = tests/userprog/rox-multichild.c \ | ||
| 93 | tests/main.c | ||
| 94 | |||
| 95 | tests/userprog/child-simple_SRC = tests/userprog/child-simple.c | ||
| 96 | tests/userprog/child-args_SRC = tests/userprog/args.c | ||
| 97 | tests/userprog/child-bad_SRC = tests/userprog/child-bad.c tests/main.c | ||
| 98 | tests/userprog/child-close_SRC = tests/userprog/child-close.c | ||
| 99 | tests/userprog/child-rox_SRC = tests/userprog/child-rox.c | ||
| 100 | |||
| 101 | $(foreach prog,$(tests/userprog_PROGS),$(eval $(prog)_SRC += tests/lib.c)) | ||
| 102 | |||
| 103 | tests/userprog/args-single_ARGS = onearg | ||
| 104 | tests/userprog/args-multiple_ARGS = some arguments for you! | ||
| 105 | tests/userprog/args-many_ARGS = a b c d e f g h i j k l m n o p q r s t u v | ||
| 106 | tests/userprog/args-dbl-space_ARGS = two spaces! | ||
| 107 | tests/userprog/multi-recurse_ARGS = 15 | ||
| 108 | |||
| 109 | tests/userprog/open-normal_PUTFILES += tests/userprog/sample.txt | ||
| 110 | tests/userprog/open-boundary_PUTFILES += tests/userprog/sample.txt | ||
| 111 | tests/userprog/open-twice_PUTFILES += tests/userprog/sample.txt | ||
| 112 | tests/userprog/close-normal_PUTFILES += tests/userprog/sample.txt | ||
| 113 | tests/userprog/close-twice_PUTFILES += tests/userprog/sample.txt | ||
| 114 | tests/userprog/read-normal_PUTFILES += tests/userprog/sample.txt | ||
| 115 | tests/userprog/read-bad-ptr_PUTFILES += tests/userprog/sample.txt | ||
| 116 | tests/userprog/read-boundary_PUTFILES += tests/userprog/sample.txt | ||
| 117 | tests/userprog/read-zero_PUTFILES += tests/userprog/sample.txt | ||
| 118 | tests/userprog/write-normal_PUTFILES += tests/userprog/sample.txt | ||
| 119 | tests/userprog/write-bad-ptr_PUTFILES += tests/userprog/sample.txt | ||
| 120 | tests/userprog/write-boundary_PUTFILES += tests/userprog/sample.txt | ||
| 121 | tests/userprog/write-zero_PUTFILES += tests/userprog/sample.txt | ||
| 122 | tests/userprog/multi-child-fd_PUTFILES += tests/userprog/sample.txt | ||
| 123 | |||
| 124 | tests/userprog/exec-once_PUTFILES += tests/userprog/child-simple | ||
| 125 | tests/userprog/exec-multiple_PUTFILES += tests/userprog/child-simple | ||
| 126 | tests/userprog/wait-simple_PUTFILES += tests/userprog/child-simple | ||
| 127 | tests/userprog/wait-twice_PUTFILES += tests/userprog/child-simple | ||
| 128 | |||
| 129 | tests/userprog/exec-arg_PUTFILES += tests/userprog/child-args | ||
| 130 | tests/userprog/multi-child-fd_PUTFILES += tests/userprog/child-close | ||
| 131 | tests/userprog/wait-killed_PUTFILES += tests/userprog/child-bad | ||
| 132 | tests/userprog/rox-child_PUTFILES += tests/userprog/child-rox | ||
| 133 | tests/userprog/rox-multichild_PUTFILES += tests/userprog/child-rox | ||
diff --git a/pintos-progos/tests/userprog/Rubric.functionality b/pintos-progos/tests/userprog/Rubric.functionality new file mode 100644 index 0000000..ea76c44 --- /dev/null +++ b/pintos-progos/tests/userprog/Rubric.functionality | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | Functionality of system calls: | ||
| 2 | - Test argument passing on Pintos command line. | ||
| 3 | 3 args-none | ||
| 4 | 3 args-single | ||
| 5 | 3 args-multiple | ||
| 6 | 3 args-many | ||
| 7 | 3 args-dbl-space | ||
| 8 | |||
| 9 | - Test "create" system call. | ||
| 10 | 3 create-empty | ||
| 11 | 3 create-long | ||
| 12 | 3 create-normal | ||
| 13 | 3 create-exists | ||
| 14 | |||
| 15 | - Test "open" system call. | ||
| 16 | 3 open-missing | ||
| 17 | 3 open-normal | ||
| 18 | 3 open-twice | ||
| 19 | |||
| 20 | - Test "read" system call. | ||
| 21 | 3 read-normal | ||
| 22 | 3 read-zero | ||
| 23 | |||
| 24 | - Test "write" system call. | ||
| 25 | 3 write-normal | ||
| 26 | 3 write-zero | ||
| 27 | |||
| 28 | - Test "close" system call. | ||
| 29 | 3 close-normal | ||
| 30 | |||
| 31 | - Test "exec" system call. | ||
| 32 | 5 exec-once | ||
| 33 | 5 exec-multiple | ||
| 34 | 5 exec-arg | ||
| 35 | |||
| 36 | - Test "wait" system call. | ||
| 37 | 5 wait-simple | ||
| 38 | 5 wait-twice | ||
| 39 | |||
| 40 | - Test "exit" system call. | ||
| 41 | 5 exit | ||
| 42 | |||
| 43 | - Test "halt" system call. | ||
| 44 | 3 halt | ||
| 45 | |||
| 46 | - Test recursive execution of user programs. | ||
| 47 | 15 multi-recurse | ||
| 48 | |||
| 49 | - Test read-only executable feature. | ||
| 50 | 3 rox-simple | ||
| 51 | 3 rox-child | ||
| 52 | 3 rox-multichild | ||
diff --git a/pintos-progos/tests/userprog/Rubric.robustness b/pintos-progos/tests/userprog/Rubric.robustness new file mode 100644 index 0000000..b7d1035 --- /dev/null +++ b/pintos-progos/tests/userprog/Rubric.robustness | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | Robustness of system calls: | ||
| 2 | - Test robustness of file descriptor handling. | ||
| 3 | 2 close-stdin | ||
| 4 | 2 close-stdout | ||
| 5 | 2 close-bad-fd | ||
| 6 | 2 close-twice | ||
| 7 | 2 read-bad-fd | ||
| 8 | 2 read-stdout | ||
| 9 | 2 write-bad-fd | ||
| 10 | 2 write-stdin | ||
| 11 | 2 multi-child-fd | ||
| 12 | |||
| 13 | - Test robustness of pointer handling. | ||
| 14 | 3 create-bad-ptr | ||
| 15 | 3 exec-bad-ptr | ||
| 16 | 3 open-bad-ptr | ||
| 17 | 3 read-bad-ptr | ||
| 18 | 3 write-bad-ptr | ||
| 19 | |||
| 20 | - Test robustness of buffer copying across page boundaries. | ||
| 21 | 3 create-bound | ||
| 22 | 3 open-boundary | ||
| 23 | 3 read-boundary | ||
| 24 | 3 write-boundary | ||
| 25 | |||
| 26 | - Test handling of null pointer and empty strings. | ||
| 27 | 2 create-null | ||
| 28 | 2 open-null | ||
| 29 | 2 open-empty | ||
| 30 | |||
| 31 | - Test robustness of system call implementation. | ||
| 32 | 3 sc-bad-arg | ||
| 33 | 3 sc-bad-sp | ||
| 34 | 5 sc-boundary | ||
| 35 | 5 sc-boundary-2 | ||
| 36 | |||
| 37 | - Test robustness of "exec" and "wait" system calls. | ||
| 38 | 5 exec-missing | ||
| 39 | 5 wait-bad-pid | ||
| 40 | 5 wait-killed | ||
| 41 | |||
| 42 | - Test robustness of exception handling. | ||
| 43 | 1 bad-read | ||
| 44 | 1 bad-write | ||
| 45 | 1 bad-jump | ||
| 46 | 1 bad-read2 | ||
| 47 | 1 bad-write2 | ||
| 48 | 1 bad-jump2 | ||
diff --git a/pintos-progos/tests/userprog/args-dbl-space.ck b/pintos-progos/tests/userprog/args-dbl-space.ck new file mode 100644 index 0000000..dfbcf4b --- /dev/null +++ b/pintos-progos/tests/userprog/args-dbl-space.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (args) begin | ||
| 7 | (args) argc = 3 | ||
| 8 | (args) argv[0] = 'args-dbl-space' | ||
| 9 | (args) argv[1] = 'two' | ||
| 10 | (args) argv[2] = 'spaces!' | ||
| 11 | (args) argv[3] = null | ||
| 12 | (args) end | ||
| 13 | args-dbl-space: exit(0) | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/userprog/args-many.ck b/pintos-progos/tests/userprog/args-many.ck new file mode 100644 index 0000000..214574a --- /dev/null +++ b/pintos-progos/tests/userprog/args-many.ck | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (args) begin | ||
| 7 | (args) argc = 23 | ||
| 8 | (args) argv[0] = 'args-many' | ||
| 9 | (args) argv[1] = 'a' | ||
| 10 | (args) argv[2] = 'b' | ||
| 11 | (args) argv[3] = 'c' | ||
| 12 | (args) argv[4] = 'd' | ||
| 13 | (args) argv[5] = 'e' | ||
| 14 | (args) argv[6] = 'f' | ||
| 15 | (args) argv[7] = 'g' | ||
| 16 | (args) argv[8] = 'h' | ||
| 17 | (args) argv[9] = 'i' | ||
| 18 | (args) argv[10] = 'j' | ||
| 19 | (args) argv[11] = 'k' | ||
| 20 | (args) argv[12] = 'l' | ||
| 21 | (args) argv[13] = 'm' | ||
| 22 | (args) argv[14] = 'n' | ||
| 23 | (args) argv[15] = 'o' | ||
| 24 | (args) argv[16] = 'p' | ||
| 25 | (args) argv[17] = 'q' | ||
| 26 | (args) argv[18] = 'r' | ||
| 27 | (args) argv[19] = 's' | ||
| 28 | (args) argv[20] = 't' | ||
| 29 | (args) argv[21] = 'u' | ||
| 30 | (args) argv[22] = 'v' | ||
| 31 | (args) argv[23] = null | ||
| 32 | (args) end | ||
| 33 | args-many: exit(0) | ||
| 34 | EOF | ||
| 35 | pass; | ||
diff --git a/pintos-progos/tests/userprog/args-multiple.ck b/pintos-progos/tests/userprog/args-multiple.ck new file mode 100644 index 0000000..227e6cc --- /dev/null +++ b/pintos-progos/tests/userprog/args-multiple.ck | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (args) begin | ||
| 7 | (args) argc = 5 | ||
| 8 | (args) argv[0] = 'args-multiple' | ||
| 9 | (args) argv[1] = 'some' | ||
| 10 | (args) argv[2] = 'arguments' | ||
| 11 | (args) argv[3] = 'for' | ||
| 12 | (args) argv[4] = 'you!' | ||
| 13 | (args) argv[5] = null | ||
| 14 | (args) end | ||
| 15 | args-multiple: exit(0) | ||
| 16 | EOF | ||
| 17 | pass; | ||
diff --git a/pintos-progos/tests/userprog/args-none.ck b/pintos-progos/tests/userprog/args-none.ck new file mode 100644 index 0000000..146318e --- /dev/null +++ b/pintos-progos/tests/userprog/args-none.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (args) begin | ||
| 7 | (args) argc = 1 | ||
| 8 | (args) argv[0] = 'args-none' | ||
| 9 | (args) argv[1] = null | ||
| 10 | (args) end | ||
| 11 | args-none: exit(0) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/args-single.ck b/pintos-progos/tests/userprog/args-single.ck new file mode 100644 index 0000000..24582b4 --- /dev/null +++ b/pintos-progos/tests/userprog/args-single.ck | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (args) begin | ||
| 7 | (args) argc = 2 | ||
| 8 | (args) argv[0] = 'args-single' | ||
| 9 | (args) argv[1] = 'onearg' | ||
| 10 | (args) argv[2] = null | ||
| 11 | (args) end | ||
| 12 | args-single: exit(0) | ||
| 13 | EOF | ||
| 14 | pass; | ||
diff --git a/pintos-progos/tests/userprog/args.c b/pintos-progos/tests/userprog/args.c new file mode 100644 index 0000000..20eda44 --- /dev/null +++ b/pintos-progos/tests/userprog/args.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* Prints the command-line arguments. | ||
| 2 | This program is used for all of the args-* tests. Grading is | ||
| 3 | done differently for each of the args-* tests based on the | ||
| 4 | output. */ | ||
| 5 | |||
| 6 | #include "tests/lib.h" | ||
| 7 | |||
| 8 | int | ||
| 9 | main (int argc, char *argv[]) | ||
| 10 | { | ||
| 11 | int i; | ||
| 12 | |||
| 13 | test_name = "args"; | ||
| 14 | |||
| 15 | msg ("begin"); | ||
| 16 | msg ("argc = %d", argc); | ||
| 17 | for (i = 0; i <= argc; i++) | ||
| 18 | if (argv[i] != NULL) | ||
| 19 | msg ("argv[%d] = '%s'", i, argv[i]); | ||
| 20 | else | ||
| 21 | msg ("argv[%d] = null", i); | ||
| 22 | msg ("end"); | ||
| 23 | |||
| 24 | return 0; | ||
| 25 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-jump.c b/pintos-progos/tests/userprog/bad-jump.c new file mode 100644 index 0000000..51b7c9f --- /dev/null +++ b/pintos-progos/tests/userprog/bad-jump.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* This program attempts to execute code at address 0, which is not mapped. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("Congratulations - you have successfully called NULL: %d", | ||
| 11 | ((int (*)(void))NULL)()); | ||
| 12 | fail ("should have exited with -1"); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-jump.ck b/pintos-progos/tests/userprog/bad-jump.ck new file mode 100644 index 0000000..e1c178b --- /dev/null +++ b/pintos-progos/tests/userprog/bad-jump.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-jump) begin | ||
| 7 | bad-jump: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/bad-jump2.c b/pintos-progos/tests/userprog/bad-jump2.c new file mode 100644 index 0000000..dc7c2a7 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-jump2.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* This program attempts to execute code at a kernel virtual address. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("Congratulations - you have successfully called kernel code: %d", | ||
| 11 | ((int (*)(void))0xC0000000)()); | ||
| 12 | fail ("should have exited with -1"); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-jump2.ck b/pintos-progos/tests/userprog/bad-jump2.ck new file mode 100644 index 0000000..35f0f97 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-jump2.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-jump2) begin | ||
| 7 | bad-jump2: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/bad-read.c b/pintos-progos/tests/userprog/bad-read.c new file mode 100644 index 0000000..904c278 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-read.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* This program attempts to read memory at an address that is not mapped. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("Congratulations - you have successfully dereferenced NULL: %d", | ||
| 11 | *(int *)NULL); | ||
| 12 | fail ("should have exited with -1"); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-read.ck b/pintos-progos/tests/userprog/bad-read.ck new file mode 100644 index 0000000..4d4d926 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-read.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-read) begin | ||
| 7 | bad-read: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/bad-read2.c b/pintos-progos/tests/userprog/bad-read2.c new file mode 100644 index 0000000..a2fc237 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-read2.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* This program attempts to read kernel memory. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("Congratulations - you have successfully read kernel memory: %d", | ||
| 11 | *(int *)0xC0000000); | ||
| 12 | fail ("should have exited with -1"); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-read2.ck b/pintos-progos/tests/userprog/bad-read2.ck new file mode 100644 index 0000000..fa27c7d --- /dev/null +++ b/pintos-progos/tests/userprog/bad-read2.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-read2) begin | ||
| 7 | bad-read2: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/bad-write.c b/pintos-progos/tests/userprog/bad-write.c new file mode 100644 index 0000000..000c26b --- /dev/null +++ b/pintos-progos/tests/userprog/bad-write.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* This program attempts to write to memory at an address that is not mapped. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | *(int *)NULL = 42; | ||
| 11 | fail ("should have exited with -1"); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-write.ck b/pintos-progos/tests/userprog/bad-write.ck new file mode 100644 index 0000000..d213b49 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-write.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-write) begin | ||
| 7 | bad-write: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/bad-write2.c b/pintos-progos/tests/userprog/bad-write2.c new file mode 100644 index 0000000..753da1e --- /dev/null +++ b/pintos-progos/tests/userprog/bad-write2.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* This program attempts to write to kernel memory. | ||
| 2 | This should terminate the process with a -1 exit code. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | *(int *)0xC0000000 = 42; | ||
| 11 | fail ("should have exited with -1"); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/userprog/bad-write2.ck b/pintos-progos/tests/userprog/bad-write2.ck new file mode 100644 index 0000000..c6a3420 --- /dev/null +++ b/pintos-progos/tests/userprog/bad-write2.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, [<<'EOF']); | ||
| 6 | (bad-write2) begin | ||
| 7 | bad-write2: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/boundary.c b/pintos-progos/tests/userprog/boundary.c new file mode 100644 index 0000000..59907ec --- /dev/null +++ b/pintos-progos/tests/userprog/boundary.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* Utility function for tests that try to break system calls by | ||
| 2 | passing them data that crosses from one virtual page to | ||
| 3 | another. */ | ||
| 4 | |||
| 5 | #include <inttypes.h> | ||
| 6 | #include <round.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include "tests/userprog/boundary.h" | ||
| 9 | |||
| 10 | static char dst[8192]; | ||
| 11 | |||
| 12 | /* Returns the beginning of a page. There are at least 2048 | ||
| 13 | modifiable bytes on either side of the pointer returned. */ | ||
| 14 | void * | ||
| 15 | get_boundary_area (void) | ||
| 16 | { | ||
| 17 | char *p = (char *) ROUND_UP ((uintptr_t) dst, 4096); | ||
| 18 | if (p - dst < 2048) | ||
| 19 | p += 4096; | ||
| 20 | return p; | ||
| 21 | } | ||
| 22 | |||
| 23 | /* Returns a copy of SRC split across the boundary between two | ||
| 24 | pages. */ | ||
| 25 | char * | ||
| 26 | copy_string_across_boundary (const char *src) | ||
| 27 | { | ||
| 28 | char *p = get_boundary_area (); | ||
| 29 | p -= strlen (src) < 4096 ? strlen (src) / 2 : 4096; | ||
| 30 | strlcpy (p, src, 4096); | ||
| 31 | return p; | ||
| 32 | } | ||
| 33 | |||
diff --git a/pintos-progos/tests/userprog/boundary.h b/pintos-progos/tests/userprog/boundary.h new file mode 100644 index 0000000..c8e4b3b --- /dev/null +++ b/pintos-progos/tests/userprog/boundary.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef TESTS_USERPROG_BOUNDARY_H | ||
| 2 | #define TESTS_USERPROG_BOUNDARY_H | ||
| 3 | |||
| 4 | void *get_boundary_area (void); | ||
| 5 | char *copy_string_across_boundary (const char *); | ||
| 6 | |||
| 7 | #endif /* tests/userprog/boundary.h */ | ||
diff --git a/pintos-progos/tests/userprog/child-bad.c b/pintos-progos/tests/userprog/child-bad.c new file mode 100644 index 0000000..77d7a69 --- /dev/null +++ b/pintos-progos/tests/userprog/child-bad.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Child process run by wait-killed test. | ||
| 2 | Sets the stack pointer (%esp) to an invalid value and invokes | ||
| 3 | a system call, which should then terminate the process with a | ||
| 4 | -1 exit code. */ | ||
| 5 | |||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | asm volatile ("movl $0x20101234, %esp; int $0x30"); | ||
| 13 | fail ("should have exited with -1"); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/child-close.c b/pintos-progos/tests/userprog/child-close.c new file mode 100644 index 0000000..ac948c8 --- /dev/null +++ b/pintos-progos/tests/userprog/child-close.c | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* Child process run by multi-child-fd test. | ||
| 2 | |||
| 3 | Attempts to close the file descriptor passed as the first | ||
| 4 | command-line argument. This is invalid, because file | ||
| 5 | descriptors are not inherited in Pintos. Two results are | ||
| 6 | allowed: either the system call should return without taking | ||
| 7 | any action, or the kernel should terminate the process with a | ||
| 8 | -1 exit code. */ | ||
| 9 | |||
| 10 | #include <ctype.h> | ||
| 11 | #include <stdio.h> | ||
| 12 | #include <stdlib.h> | ||
| 13 | #include <syscall.h> | ||
| 14 | #include "tests/lib.h" | ||
| 15 | |||
| 16 | const char *test_name = "child-close"; | ||
| 17 | |||
| 18 | int | ||
| 19 | main (int argc UNUSED, char *argv[]) | ||
| 20 | { | ||
| 21 | msg ("begin"); | ||
| 22 | if (!isdigit (*argv[1])) | ||
| 23 | fail ("bad command-line arguments"); | ||
| 24 | close (atoi (argv[1])); | ||
| 25 | msg ("end"); | ||
| 26 | |||
| 27 | return 0; | ||
| 28 | } | ||
diff --git a/pintos-progos/tests/userprog/child-rox.c b/pintos-progos/tests/userprog/child-rox.c new file mode 100644 index 0000000..aba808b --- /dev/null +++ b/pintos-progos/tests/userprog/child-rox.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* Child process run by rox-child and rox-multichild tests. | ||
| 2 | Opens and tries to write to its own executable, verifying that | ||
| 3 | that is disallowed. | ||
| 4 | Then recursively executes itself to the depth indicated by the | ||
| 5 | first command-line argument. */ | ||
| 6 | |||
| 7 | #include <ctype.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | #include <syscall.h> | ||
| 11 | #include "tests/lib.h" | ||
| 12 | |||
| 13 | const char *test_name = "child-rox"; | ||
| 14 | |||
| 15 | static void | ||
| 16 | try_write (void) | ||
| 17 | { | ||
| 18 | int handle; | ||
| 19 | char buffer[19]; | ||
| 20 | |||
| 21 | quiet = true; | ||
| 22 | CHECK ((handle = open ("child-rox")) > 1, "open \"child-rox\""); | ||
| 23 | quiet = false; | ||
| 24 | |||
| 25 | CHECK (write (handle, buffer, sizeof buffer) == 0, | ||
| 26 | "try to write \"child-rox\""); | ||
| 27 | |||
| 28 | close (handle); | ||
| 29 | } | ||
| 30 | |||
| 31 | int | ||
| 32 | main (int argc UNUSED, char *argv[]) | ||
| 33 | { | ||
| 34 | msg ("begin"); | ||
| 35 | try_write (); | ||
| 36 | |||
| 37 | if (!isdigit (*argv[1])) | ||
| 38 | fail ("bad command-line arguments"); | ||
| 39 | if (atoi (argv[1]) > 1) | ||
| 40 | { | ||
| 41 | char cmd[128]; | ||
| 42 | int child; | ||
| 43 | |||
| 44 | snprintf (cmd, sizeof cmd, "child-rox %d", atoi (argv[1]) - 1); | ||
| 45 | CHECK ((child = exec (cmd)) != -1, "exec \"%s\"", cmd); | ||
| 46 | quiet = true; | ||
| 47 | CHECK (wait (child) == 12, "wait for \"child-rox\""); | ||
| 48 | quiet = false; | ||
| 49 | } | ||
| 50 | |||
| 51 | try_write (); | ||
| 52 | msg ("end"); | ||
| 53 | |||
| 54 | return 12; | ||
| 55 | } | ||
diff --git a/pintos-progos/tests/userprog/child-simple.c b/pintos-progos/tests/userprog/child-simple.c new file mode 100644 index 0000000..0d2dacf --- /dev/null +++ b/pintos-progos/tests/userprog/child-simple.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* Child process run by exec-multiple, exec-one, wait-simple, and | ||
| 2 | wait-twice tests. | ||
| 3 | Just prints a single message and terminates. */ | ||
| 4 | |||
| 5 | #include <stdio.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | |||
| 8 | const char *test_name = "child-simple"; | ||
| 9 | |||
| 10 | int | ||
| 11 | main (void) | ||
| 12 | { | ||
| 13 | msg ("run"); | ||
| 14 | return 81; | ||
| 15 | } | ||
diff --git a/pintos-progos/tests/userprog/close-bad-fd.c b/pintos-progos/tests/userprog/close-bad-fd.c new file mode 100644 index 0000000..f63bb9a --- /dev/null +++ b/pintos-progos/tests/userprog/close-bad-fd.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tries to close an invalid fd, which must either fail silently | ||
| 2 | or terminate with exit code -1. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | close (0x20101234); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/close-bad-fd.ck b/pintos-progos/tests/userprog/close-bad-fd.ck new file mode 100644 index 0000000..497b17c --- /dev/null +++ b/pintos-progos/tests/userprog/close-bad-fd.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (close-bad-fd) begin | ||
| 7 | (close-bad-fd) end | ||
| 8 | close-bad-fd: exit(0) | ||
| 9 | EOF | ||
| 10 | (close-bad-fd) begin | ||
| 11 | close-bad-fd: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/close-normal.c b/pintos-progos/tests/userprog/close-normal.c new file mode 100644 index 0000000..8ce04e3 --- /dev/null +++ b/pintos-progos/tests/userprog/close-normal.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Opens a file and then closes it. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle; | ||
| 11 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 12 | msg ("close \"sample.txt\""); | ||
| 13 | close (handle); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/close-normal.ck b/pintos-progos/tests/userprog/close-normal.ck new file mode 100644 index 0000000..fe41342 --- /dev/null +++ b/pintos-progos/tests/userprog/close-normal.ck | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (close-normal) begin | ||
| 7 | (close-normal) open "sample.txt" | ||
| 8 | (close-normal) close "sample.txt" | ||
| 9 | (close-normal) end | ||
| 10 | close-normal: exit(0) | ||
| 11 | EOF | ||
| 12 | pass; | ||
diff --git a/pintos-progos/tests/userprog/close-stdin.c b/pintos-progos/tests/userprog/close-stdin.c new file mode 100644 index 0000000..9bbf9f2 --- /dev/null +++ b/pintos-progos/tests/userprog/close-stdin.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tries to close the keyboard input stream, which must either | ||
| 2 | fail silently or terminate with exit code -1. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | close (0); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/close-stdin.ck b/pintos-progos/tests/userprog/close-stdin.ck new file mode 100644 index 0000000..3d28507 --- /dev/null +++ b/pintos-progos/tests/userprog/close-stdin.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (close-stdin) begin | ||
| 7 | (close-stdin) end | ||
| 8 | close-stdin: exit(0) | ||
| 9 | EOF | ||
| 10 | (close-stdin) begin | ||
| 11 | close-stdin: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/close-stdout.c b/pintos-progos/tests/userprog/close-stdout.c new file mode 100644 index 0000000..886523f --- /dev/null +++ b/pintos-progos/tests/userprog/close-stdout.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tries to close the console output stream, which must either | ||
| 2 | fail silently or terminate with exit code -1. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | close (1); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/close-stdout.ck b/pintos-progos/tests/userprog/close-stdout.ck new file mode 100644 index 0000000..3cbbcff --- /dev/null +++ b/pintos-progos/tests/userprog/close-stdout.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (close-stdout) begin | ||
| 7 | (close-stdout) end | ||
| 8 | close-stdout: exit(0) | ||
| 9 | EOF | ||
| 10 | (close-stdout) begin | ||
| 11 | close-stdout: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/close-twice.c b/pintos-progos/tests/userprog/close-twice.c new file mode 100644 index 0000000..830bccf --- /dev/null +++ b/pintos-progos/tests/userprog/close-twice.c | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* Opens a file and then tries to close it twice. The second | ||
| 2 | close must either fail silently or terminate with exit code | ||
| 3 | -1. */ | ||
| 4 | |||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | int handle; | ||
| 13 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 14 | msg ("close \"sample.txt\""); | ||
| 15 | close (handle); | ||
| 16 | msg ("close \"sample.txt\" again"); | ||
| 17 | close (handle); | ||
| 18 | } | ||
diff --git a/pintos-progos/tests/userprog/close-twice.ck b/pintos-progos/tests/userprog/close-twice.ck new file mode 100644 index 0000000..deb55a6 --- /dev/null +++ b/pintos-progos/tests/userprog/close-twice.ck | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (close-twice) begin | ||
| 7 | (close-twice) open "sample.txt" | ||
| 8 | (close-twice) close "sample.txt" | ||
| 9 | (close-twice) close "sample.txt" again | ||
| 10 | (close-twice) end | ||
| 11 | close-twice: exit(0) | ||
| 12 | EOF | ||
| 13 | (close-twice) begin | ||
| 14 | (close-twice) open "sample.txt" | ||
| 15 | (close-twice) close "sample.txt" | ||
| 16 | (close-twice) close "sample.txt" again | ||
| 17 | close-twice: exit(-1) | ||
| 18 | EOF | ||
| 19 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-bad-ptr.c b/pintos-progos/tests/userprog/create-bad-ptr.c new file mode 100644 index 0000000..4a07bb3 --- /dev/null +++ b/pintos-progos/tests/userprog/create-bad-ptr.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* Passes a bad pointer to the create system call, | ||
| 2 | which must cause the process to be terminated with exit code | ||
| 3 | -1. */ | ||
| 4 | |||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | msg ("create(0x20101234): %d", create ((char *) 0x20101234, 0)); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/userprog/create-bad-ptr.ck b/pintos-progos/tests/userprog/create-bad-ptr.ck new file mode 100644 index 0000000..ac13405 --- /dev/null +++ b/pintos-progos/tests/userprog/create-bad-ptr.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-bad-ptr) begin | ||
| 7 | create-bad-ptr: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-bound.c b/pintos-progos/tests/userprog/create-bound.c new file mode 100644 index 0000000..0a829f3 --- /dev/null +++ b/pintos-progos/tests/userprog/create-bound.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Opens a file whose name spans the boundary between two pages. | ||
| 2 | This is valid, so it must succeed. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/userprog/boundary.h" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | msg ("create(\"quux.dat\"): %d", | ||
| 13 | create (copy_string_across_boundary ("quux.dat"), 0)); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/create-bound.ck b/pintos-progos/tests/userprog/create-bound.ck new file mode 100644 index 0000000..7656b7f --- /dev/null +++ b/pintos-progos/tests/userprog/create-bound.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-bound) begin | ||
| 7 | (create-bound) create("quux.dat"): 1 | ||
| 8 | (create-bound) end | ||
| 9 | create-bound: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-empty.c b/pintos-progos/tests/userprog/create-empty.c new file mode 100644 index 0000000..fa26b43 --- /dev/null +++ b/pintos-progos/tests/userprog/create-empty.c | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* Tries to create a file with the empty string as its name. */ | ||
| 2 | |||
| 3 | #include "tests/lib.h" | ||
| 4 | #include "tests/main.h" | ||
| 5 | |||
| 6 | void | ||
| 7 | test_main (void) | ||
| 8 | { | ||
| 9 | msg ("create(\"\"): %d", create ("", 0)); | ||
| 10 | } | ||
diff --git a/pintos-progos/tests/userprog/create-empty.ck b/pintos-progos/tests/userprog/create-empty.ck new file mode 100644 index 0000000..93a1058 --- /dev/null +++ b/pintos-progos/tests/userprog/create-empty.ck | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (create-empty) begin | ||
| 7 | (create-empty) create(""): 0 | ||
| 8 | (create-empty) end | ||
| 9 | create-empty: exit(0) | ||
| 10 | EOF | ||
| 11 | (create-empty) begin | ||
| 12 | create-empty: exit(-1) | ||
| 13 | EOF | ||
| 14 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-exists.c b/pintos-progos/tests/userprog/create-exists.c new file mode 100644 index 0000000..d395008 --- /dev/null +++ b/pintos-progos/tests/userprog/create-exists.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Verifies that trying to create a file under a name that | ||
| 2 | already exists will fail. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | CHECK (create ("quux.dat", 0), "create quux.dat"); | ||
| 12 | CHECK (create ("warble.dat", 0), "create warble.dat"); | ||
| 13 | CHECK (!create ("quux.dat", 0), "try to re-create quux.dat"); | ||
| 14 | CHECK (create ("baffle.dat", 0), "create baffle.dat"); | ||
| 15 | CHECK (!create ("warble.dat", 0), "try to re-create quux.dat"); | ||
| 16 | } | ||
diff --git a/pintos-progos/tests/userprog/create-exists.ck b/pintos-progos/tests/userprog/create-exists.ck new file mode 100644 index 0000000..006885e --- /dev/null +++ b/pintos-progos/tests/userprog/create-exists.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-exists) begin | ||
| 7 | (create-exists) create quux.dat | ||
| 8 | (create-exists) create warble.dat | ||
| 9 | (create-exists) try to re-create quux.dat | ||
| 10 | (create-exists) create baffle.dat | ||
| 11 | (create-exists) try to re-create quux.dat | ||
| 12 | (create-exists) end | ||
| 13 | create-exists: exit(0) | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-long.c b/pintos-progos/tests/userprog/create-long.c new file mode 100644 index 0000000..16b31bd --- /dev/null +++ b/pintos-progos/tests/userprog/create-long.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* Tries to create a file with a name that is much too long, | ||
| 2 | which must fail. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | static char name[512]; | ||
| 13 | memset (name, 'x', sizeof name); | ||
| 14 | name[sizeof name - 1] = '\0'; | ||
| 15 | |||
| 16 | msg ("create(\"x...\"): %d", create (name, 0)); | ||
| 17 | } | ||
diff --git a/pintos-progos/tests/userprog/create-long.ck b/pintos-progos/tests/userprog/create-long.ck new file mode 100644 index 0000000..628411c --- /dev/null +++ b/pintos-progos/tests/userprog/create-long.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-long) begin | ||
| 7 | (create-long) create("x..."): 0 | ||
| 8 | (create-long) end | ||
| 9 | create-long: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-normal.c b/pintos-progos/tests/userprog/create-normal.c new file mode 100644 index 0000000..3cbc463 --- /dev/null +++ b/pintos-progos/tests/userprog/create-normal.c | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* Creates an ordinary empty file. */ | ||
| 2 | |||
| 3 | #include "tests/lib.h" | ||
| 4 | #include "tests/main.h" | ||
| 5 | |||
| 6 | void | ||
| 7 | test_main (void) | ||
| 8 | { | ||
| 9 | CHECK (create ("quux.dat", 0), "create quux.dat"); | ||
| 10 | } | ||
diff --git a/pintos-progos/tests/userprog/create-normal.ck b/pintos-progos/tests/userprog/create-normal.ck new file mode 100644 index 0000000..ca74a6e --- /dev/null +++ b/pintos-progos/tests/userprog/create-normal.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-normal) begin | ||
| 7 | (create-normal) create quux.dat | ||
| 8 | (create-normal) end | ||
| 9 | create-normal: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/create-null.c b/pintos-progos/tests/userprog/create-null.c new file mode 100644 index 0000000..287cb23 --- /dev/null +++ b/pintos-progos/tests/userprog/create-null.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tries to create a file with the null pointer as its name. | ||
| 2 | The process must be terminated with exit code -1. */ | ||
| 3 | |||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("create(NULL): %d", create (NULL, 0)); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/create-null.ck b/pintos-progos/tests/userprog/create-null.ck new file mode 100644 index 0000000..09b7872 --- /dev/null +++ b/pintos-progos/tests/userprog/create-null.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (create-null) begin | ||
| 7 | create-null: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exec-arg.c b/pintos-progos/tests/userprog/exec-arg.c new file mode 100644 index 0000000..82d0744 --- /dev/null +++ b/pintos-progos/tests/userprog/exec-arg.c | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* Tests argument passing to child processes. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/main.h" | ||
| 5 | |||
| 6 | void | ||
| 7 | test_main (void) | ||
| 8 | { | ||
| 9 | wait (exec ("child-args childarg")); | ||
| 10 | } | ||
diff --git a/pintos-progos/tests/userprog/exec-arg.ck b/pintos-progos/tests/userprog/exec-arg.ck new file mode 100644 index 0000000..b7533ed --- /dev/null +++ b/pintos-progos/tests/userprog/exec-arg.ck | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (exec-arg) begin | ||
| 7 | (args) begin | ||
| 8 | (args) argc = 2 | ||
| 9 | (args) argv[0] = 'child-args' | ||
| 10 | (args) argv[1] = 'childarg' | ||
| 11 | (args) argv[2] = null | ||
| 12 | (args) end | ||
| 13 | child-args: exit(0) | ||
| 14 | (exec-arg) end | ||
| 15 | exec-arg: exit(0) | ||
| 16 | EOF | ||
| 17 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exec-bad-ptr.c b/pintos-progos/tests/userprog/exec-bad-ptr.c new file mode 100644 index 0000000..0abadd3 --- /dev/null +++ b/pintos-progos/tests/userprog/exec-bad-ptr.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Passes an invalid pointer to the exec system call. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | exec ((char *) 0x20101234); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/exec-bad-ptr.ck b/pintos-progos/tests/userprog/exec-bad-ptr.ck new file mode 100644 index 0000000..63f5f78 --- /dev/null +++ b/pintos-progos/tests/userprog/exec-bad-ptr.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (exec-bad-ptr) begin | ||
| 7 | (exec-bad-ptr) end | ||
| 8 | exec-bad-ptr: exit(0) | ||
| 9 | EOF | ||
| 10 | (exec-bad-ptr) begin | ||
| 11 | exec-bad-ptr: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exec-missing.c b/pintos-progos/tests/userprog/exec-missing.c new file mode 100644 index 0000000..bf08cad --- /dev/null +++ b/pintos-progos/tests/userprog/exec-missing.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* Tries to execute a nonexistent process. | ||
| 2 | The exec system call must return -1. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | msg ("exec(\"no-such-file\"): %d", exec ("no-such-file")); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/userprog/exec-missing.ck b/pintos-progos/tests/userprog/exec-missing.ck new file mode 100644 index 0000000..0ef7aaa --- /dev/null +++ b/pintos-progos/tests/userprog/exec-missing.ck | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF', <<'EOF', <<'EOF']); | ||
| 6 | (exec-missing) begin | ||
| 7 | load: no-such-file: open failed | ||
| 8 | (exec-missing) exec("no-such-file"): -1 | ||
| 9 | (exec-missing) end | ||
| 10 | exec-missing: exit(0) | ||
| 11 | EOF | ||
| 12 | (exec-missing) begin | ||
| 13 | (exec-missing) exec("no-such-file"): -1 | ||
| 14 | (exec-missing) end | ||
| 15 | exec-missing: exit(0) | ||
| 16 | EOF | ||
| 17 | (exec-missing) begin | ||
| 18 | load: no-such-file: open failed | ||
| 19 | no-such-file: exit(-1) | ||
| 20 | (exec-missing) exec("no-such-file"): -1 | ||
| 21 | (exec-missing) end | ||
| 22 | exec-missing: exit(0) | ||
| 23 | EOF | ||
| 24 | (exec-missing) begin | ||
| 25 | load: no-such-file: open failed | ||
| 26 | (exec-missing) exec("no-such-file"): -1 | ||
| 27 | no-such-file: exit(-1) | ||
| 28 | (exec-missing) end | ||
| 29 | exec-missing: exit(0) | ||
| 30 | EOF | ||
| 31 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exec-multiple.c b/pintos-progos/tests/userprog/exec-multiple.c new file mode 100644 index 0000000..ba4c26e --- /dev/null +++ b/pintos-progos/tests/userprog/exec-multiple.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Executes and waits for multiple child processes. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | wait (exec ("child-simple")); | ||
| 11 | wait (exec ("child-simple")); | ||
| 12 | wait (exec ("child-simple")); | ||
| 13 | wait (exec ("child-simple")); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/exec-multiple.ck b/pintos-progos/tests/userprog/exec-multiple.ck new file mode 100644 index 0000000..99624cd --- /dev/null +++ b/pintos-progos/tests/userprog/exec-multiple.ck | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (exec-multiple) begin | ||
| 7 | (child-simple) run | ||
| 8 | child-simple: exit(81) | ||
| 9 | (child-simple) run | ||
| 10 | child-simple: exit(81) | ||
| 11 | (child-simple) run | ||
| 12 | child-simple: exit(81) | ||
| 13 | (child-simple) run | ||
| 14 | child-simple: exit(81) | ||
| 15 | (exec-multiple) end | ||
| 16 | exec-multiple: exit(0) | ||
| 17 | EOF | ||
| 18 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exec-once.c b/pintos-progos/tests/userprog/exec-once.c new file mode 100644 index 0000000..7bae5a1 --- /dev/null +++ b/pintos-progos/tests/userprog/exec-once.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Executes and waits for a single child process. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | wait (exec ("child-simple")); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/exec-once.ck b/pintos-progos/tests/userprog/exec-once.ck new file mode 100644 index 0000000..00b59ed --- /dev/null +++ b/pintos-progos/tests/userprog/exec-once.ck | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (exec-once) begin | ||
| 7 | (child-simple) run | ||
| 8 | child-simple: exit(81) | ||
| 9 | (exec-once) end | ||
| 10 | exec-once: exit(0) | ||
| 11 | EOF | ||
| 12 | pass; | ||
diff --git a/pintos-progos/tests/userprog/exit.c b/pintos-progos/tests/userprog/exit.c new file mode 100644 index 0000000..cb4eb8f --- /dev/null +++ b/pintos-progos/tests/userprog/exit.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tests the exit system call. */ | ||
| 2 | |||
| 3 | #include "tests/lib.h" | ||
| 4 | #include "tests/main.h" | ||
| 5 | |||
| 6 | void | ||
| 7 | test_main (void) | ||
| 8 | { | ||
| 9 | exit (57); | ||
| 10 | fail ("should have called exit(57)"); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/exit.ck b/pintos-progos/tests/userprog/exit.ck new file mode 100644 index 0000000..a552702 --- /dev/null +++ b/pintos-progos/tests/userprog/exit.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (exit) begin | ||
| 7 | exit: exit(57) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/halt.c b/pintos-progos/tests/userprog/halt.c new file mode 100644 index 0000000..4a99bce --- /dev/null +++ b/pintos-progos/tests/userprog/halt.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Tests the halt system call. */ | ||
| 2 | |||
| 3 | #include "tests/lib.h" | ||
| 4 | #include "tests/main.h" | ||
| 5 | |||
| 6 | void | ||
| 7 | test_main (void) | ||
| 8 | { | ||
| 9 | halt (); | ||
| 10 | fail ("should have halted"); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/halt.ck b/pintos-progos/tests/userprog/halt.ck new file mode 100644 index 0000000..1b701ed --- /dev/null +++ b/pintos-progos/tests/userprog/halt.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | |||
| 6 | our ($test); | ||
| 7 | my (@output) = read_text_file ("$test.output"); | ||
| 8 | |||
| 9 | common_checks ("run", @output); | ||
| 10 | |||
| 11 | fail "missing 'begin' message\n" | ||
| 12 | if !grep ($_ eq '(halt) begin', @output); | ||
| 13 | fail "found 'fail' message--halt didn't really halt\n" | ||
| 14 | if grep ($_ eq '(halt) fail', @output); | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/userprog/lib/.gitignore b/pintos-progos/tests/userprog/lib/.gitignore new file mode 100644 index 0000000..a438335 --- /dev/null +++ b/pintos-progos/tests/userprog/lib/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| *.d | |||
diff --git a/pintos-progos/tests/userprog/lib/user/.dummy b/pintos-progos/tests/userprog/lib/user/.dummy new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pintos-progos/tests/userprog/lib/user/.dummy | |||
diff --git a/pintos-progos/tests/userprog/lib/user/.gitignore b/pintos-progos/tests/userprog/lib/user/.gitignore new file mode 100644 index 0000000..a438335 --- /dev/null +++ b/pintos-progos/tests/userprog/lib/user/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| *.d | |||
diff --git a/pintos-progos/tests/userprog/multi-child-fd.c b/pintos-progos/tests/userprog/multi-child-fd.c new file mode 100644 index 0000000..48de4b4 --- /dev/null +++ b/pintos-progos/tests/userprog/multi-child-fd.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* Opens a file and then runs a subprocess that tries to close | ||
| 2 | the file. (Pintos does not have inheritance of file handles, | ||
| 3 | so this must fail.) The parent process then attempts to use | ||
| 4 | the file handle, which must succeed. */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <syscall.h> | ||
| 8 | #include "tests/userprog/sample.inc" | ||
| 9 | #include "tests/lib.h" | ||
| 10 | #include "tests/main.h" | ||
| 11 | |||
| 12 | void | ||
| 13 | test_main (void) | ||
| 14 | { | ||
| 15 | char child_cmd[128]; | ||
| 16 | int handle; | ||
| 17 | |||
| 18 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 19 | |||
| 20 | snprintf (child_cmd, sizeof child_cmd, "child-close %d", handle); | ||
| 21 | |||
| 22 | msg ("wait(exec()) = %d", wait (exec (child_cmd))); | ||
| 23 | |||
| 24 | check_file_handle (handle, "sample.txt", sample, sizeof sample - 1); | ||
| 25 | } | ||
diff --git a/pintos-progos/tests/userprog/multi-child-fd.ck b/pintos-progos/tests/userprog/multi-child-fd.ck new file mode 100644 index 0000000..d0b3a33 --- /dev/null +++ b/pintos-progos/tests/userprog/multi-child-fd.ck | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (multi-child-fd) begin | ||
| 7 | (multi-child-fd) open "sample.txt" | ||
| 8 | (child-close) begin | ||
| 9 | (child-close) end | ||
| 10 | child-close: exit(0) | ||
| 11 | (multi-child-fd) wait(exec()) = 0 | ||
| 12 | (multi-child-fd) verified contents of "sample.txt" | ||
| 13 | (multi-child-fd) end | ||
| 14 | multi-child-fd: exit(0) | ||
| 15 | EOF | ||
| 16 | (multi-child-fd) begin | ||
| 17 | (multi-child-fd) open "sample.txt" | ||
| 18 | (child-close) begin | ||
| 19 | child-close: exit(-1) | ||
| 20 | (multi-child-fd) wait(exec()) = -1 | ||
| 21 | (multi-child-fd) verified contents of "sample.txt" | ||
| 22 | (multi-child-fd) end | ||
| 23 | multi-child-fd: exit(0) | ||
| 24 | EOF | ||
| 25 | pass; | ||
diff --git a/pintos-progos/tests/userprog/multi-recurse.c b/pintos-progos/tests/userprog/multi-recurse.c new file mode 100644 index 0000000..7172ec3 --- /dev/null +++ b/pintos-progos/tests/userprog/multi-recurse.c | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* Executes itself recursively to the depth indicated by the | ||
| 2 | first command-line argument. */ | ||
| 3 | |||
| 4 | #include <debug.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | #include <stdio.h> | ||
| 7 | #include <syscall.h> | ||
| 8 | #include "tests/lib.h" | ||
| 9 | |||
| 10 | const char *test_name = "multi-recurse"; | ||
| 11 | |||
| 12 | int | ||
| 13 | main (int argc UNUSED, char *argv[]) | ||
| 14 | { | ||
| 15 | int n = atoi (argv[1]); | ||
| 16 | |||
| 17 | msg ("begin %d", n); | ||
| 18 | if (n != 0) | ||
| 19 | { | ||
| 20 | char child_cmd[128]; | ||
| 21 | pid_t child_pid; | ||
| 22 | int code; | ||
| 23 | |||
| 24 | snprintf (child_cmd, sizeof child_cmd, "multi-recurse %d", n - 1); | ||
| 25 | CHECK ((child_pid = exec (child_cmd)) != -1, "exec(\"%s\")", child_cmd); | ||
| 26 | |||
| 27 | code = wait (child_pid); | ||
| 28 | if (code != n - 1) | ||
| 29 | fail ("wait(exec(\"%s\")) returned %d", child_cmd, code); | ||
| 30 | } | ||
| 31 | |||
| 32 | msg ("end %d", n); | ||
| 33 | return n; | ||
| 34 | } | ||
diff --git a/pintos-progos/tests/userprog/multi-recurse.ck b/pintos-progos/tests/userprog/multi-recurse.ck new file mode 100644 index 0000000..41eb4a6 --- /dev/null +++ b/pintos-progos/tests/userprog/multi-recurse.ck | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (multi-recurse) begin 15 | ||
| 7 | (multi-recurse) exec("multi-recurse 14") | ||
| 8 | (multi-recurse) begin 14 | ||
| 9 | (multi-recurse) exec("multi-recurse 13") | ||
| 10 | (multi-recurse) begin 13 | ||
| 11 | (multi-recurse) exec("multi-recurse 12") | ||
| 12 | (multi-recurse) begin 12 | ||
| 13 | (multi-recurse) exec("multi-recurse 11") | ||
| 14 | (multi-recurse) begin 11 | ||
| 15 | (multi-recurse) exec("multi-recurse 10") | ||
| 16 | (multi-recurse) begin 10 | ||
| 17 | (multi-recurse) exec("multi-recurse 9") | ||
| 18 | (multi-recurse) begin 9 | ||
| 19 | (multi-recurse) exec("multi-recurse 8") | ||
| 20 | (multi-recurse) begin 8 | ||
| 21 | (multi-recurse) exec("multi-recurse 7") | ||
| 22 | (multi-recurse) begin 7 | ||
| 23 | (multi-recurse) exec("multi-recurse 6") | ||
| 24 | (multi-recurse) begin 6 | ||
| 25 | (multi-recurse) exec("multi-recurse 5") | ||
| 26 | (multi-recurse) begin 5 | ||
| 27 | (multi-recurse) exec("multi-recurse 4") | ||
| 28 | (multi-recurse) begin 4 | ||
| 29 | (multi-recurse) exec("multi-recurse 3") | ||
| 30 | (multi-recurse) begin 3 | ||
| 31 | (multi-recurse) exec("multi-recurse 2") | ||
| 32 | (multi-recurse) begin 2 | ||
| 33 | (multi-recurse) exec("multi-recurse 1") | ||
| 34 | (multi-recurse) begin 1 | ||
| 35 | (multi-recurse) exec("multi-recurse 0") | ||
| 36 | (multi-recurse) begin 0 | ||
| 37 | (multi-recurse) end 0 | ||
| 38 | multi-recurse: exit(0) | ||
| 39 | (multi-recurse) end 1 | ||
| 40 | multi-recurse: exit(1) | ||
| 41 | (multi-recurse) end 2 | ||
| 42 | multi-recurse: exit(2) | ||
| 43 | (multi-recurse) end 3 | ||
| 44 | multi-recurse: exit(3) | ||
| 45 | (multi-recurse) end 4 | ||
| 46 | multi-recurse: exit(4) | ||
| 47 | (multi-recurse) end 5 | ||
| 48 | multi-recurse: exit(5) | ||
| 49 | (multi-recurse) end 6 | ||
| 50 | multi-recurse: exit(6) | ||
| 51 | (multi-recurse) end 7 | ||
| 52 | multi-recurse: exit(7) | ||
| 53 | (multi-recurse) end 8 | ||
| 54 | multi-recurse: exit(8) | ||
| 55 | (multi-recurse) end 9 | ||
| 56 | multi-recurse: exit(9) | ||
| 57 | (multi-recurse) end 10 | ||
| 58 | multi-recurse: exit(10) | ||
| 59 | (multi-recurse) end 11 | ||
| 60 | multi-recurse: exit(11) | ||
| 61 | (multi-recurse) end 12 | ||
| 62 | multi-recurse: exit(12) | ||
| 63 | (multi-recurse) end 13 | ||
| 64 | multi-recurse: exit(13) | ||
| 65 | (multi-recurse) end 14 | ||
| 66 | multi-recurse: exit(14) | ||
| 67 | (multi-recurse) end 15 | ||
| 68 | multi-recurse: exit(15) | ||
| 69 | EOF | ||
| 70 | pass; | ||
diff --git a/pintos-progos/tests/userprog/no-vm/Make.tests b/pintos-progos/tests/userprog/no-vm/Make.tests new file mode 100644 index 0000000..a545e18 --- /dev/null +++ b/pintos-progos/tests/userprog/no-vm/Make.tests | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # -*- makefile -*- | ||
| 2 | |||
| 3 | tests/userprog/no-vm_TESTS = tests/userprog/no-vm/multi-oom | ||
| 4 | tests/userprog/no-vm_PROGS = $(tests/userprog/no-vm_TESTS) | ||
| 5 | tests/userprog/no-vm/multi-oom_SRC = tests/userprog/no-vm/multi-oom.c \ | ||
| 6 | tests/lib.c | ||
| 7 | |||
| 8 | tests/userprog/no-vm/multi-oom.output: TIMEOUT = 360 | ||
diff --git a/pintos-progos/tests/userprog/no-vm/Rubric b/pintos-progos/tests/userprog/no-vm/Rubric new file mode 100644 index 0000000..c3816c6 --- /dev/null +++ b/pintos-progos/tests/userprog/no-vm/Rubric | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | Functionality of features that VM might break: | ||
| 2 | |||
| 3 | 1 multi-oom | ||
diff --git a/pintos-progos/tests/userprog/no-vm/multi-oom.c b/pintos-progos/tests/userprog/no-vm/multi-oom.c new file mode 100644 index 0000000..6a4472d --- /dev/null +++ b/pintos-progos/tests/userprog/no-vm/multi-oom.c | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | /* Recursively executes itself until the child fails to execute. | ||
| 2 | We expect that at least 30 copies can run. | ||
| 3 | |||
| 4 | We count how many children your kernel was able to execute | ||
| 5 | before it fails to start a new process. We require that, | ||
| 6 | if a process doesn't actually get to start, exec() must | ||
| 7 | return -1, not a valid PID. | ||
| 8 | |||
| 9 | We repeat this process 10 times, checking that your kernel | ||
| 10 | allows for the same level of depth every time. | ||
| 11 | |||
| 12 | In addition, some processes will spawn children that terminate | ||
| 13 | abnormally after allocating some resources. | ||
| 14 | |||
| 15 | Written by Godmar Back <godmar@gmail.com> | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <debug.h> | ||
| 19 | #include <stdio.h> | ||
| 20 | #include <string.h> | ||
| 21 | #include <stdlib.h> | ||
| 22 | #include <stdbool.h> | ||
| 23 | #include <syscall.h> | ||
| 24 | #include <random.h> | ||
| 25 | #include "tests/lib.h" | ||
| 26 | |||
| 27 | static const int EXPECTED_DEPTH_TO_PASS = 30; | ||
| 28 | static const int EXPECTED_REPETITIONS = 10; | ||
| 29 | |||
| 30 | const char *test_name = "multi-oom"; | ||
| 31 | |||
| 32 | enum child_termination_mode { RECURSE, CRASH }; | ||
| 33 | |||
| 34 | /* Spawn a recursive copy of ourselves, passing along instructions | ||
| 35 | for the child. */ | ||
| 36 | static pid_t | ||
| 37 | spawn_child (int c, enum child_termination_mode mode) | ||
| 38 | { | ||
| 39 | char child_cmd[128]; | ||
| 40 | snprintf (child_cmd, sizeof child_cmd, | ||
| 41 | "%s %d %s", test_name, c, mode == CRASH ? "-k" : ""); | ||
| 42 | return exec (child_cmd); | ||
| 43 | } | ||
| 44 | |||
| 45 | /* Open a number of files (and fail to close them). | ||
| 46 | The kernel must free any kernel resources associated | ||
| 47 | with these file descriptors. */ | ||
| 48 | static void | ||
| 49 | consume_some_resources (void) | ||
| 50 | { | ||
| 51 | int fd, fdmax = 126; | ||
| 52 | |||
| 53 | /* Open as many files as we can, up to fdmax. | ||
| 54 | Depending on how file descriptors are allocated inside | ||
| 55 | the kernel, open() may fail if the kernel is low on memory. | ||
| 56 | A low-memory condition in open() should not lead to the | ||
| 57 | termination of the process. */ | ||
| 58 | for (fd = 0; fd < fdmax; fd++) | ||
| 59 | if (open (test_name) == -1) | ||
| 60 | break; | ||
| 61 | } | ||
| 62 | |||
| 63 | /* Consume some resources, then terminate this process | ||
| 64 | in some abnormal way. */ | ||
| 65 | static int NO_INLINE | ||
| 66 | consume_some_resources_and_die (int seed) | ||
| 67 | { | ||
| 68 | consume_some_resources (); | ||
| 69 | random_init (seed); | ||
| 70 | int *PHYS_BASE = (int *)0xC0000000; | ||
| 71 | |||
| 72 | switch (random_ulong () % 5) | ||
| 73 | { | ||
| 74 | case 0: | ||
| 75 | *(int *) NULL = 42; | ||
| 76 | |||
| 77 | case 1: | ||
| 78 | return *(int *) NULL; | ||
| 79 | |||
| 80 | case 2: | ||
| 81 | return *PHYS_BASE; | ||
| 82 | |||
| 83 | case 3: | ||
| 84 | *PHYS_BASE = 42; | ||
| 85 | |||
| 86 | case 4: | ||
| 87 | open ((char *)PHYS_BASE); | ||
| 88 | exit (-1); | ||
| 89 | |||
| 90 | default: | ||
| 91 | NOT_REACHED (); | ||
| 92 | } | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | /* The first copy is invoked without command line arguments. | ||
| 97 | Subsequent copies are invoked with a parameter 'depth' | ||
| 98 | that describes how many parent processes preceded them. | ||
| 99 | Each process spawns one or multiple recursive copies of | ||
| 100 | itself, passing 'depth+1' as depth. | ||
| 101 | |||
| 102 | Some children are started with the '-k' flag, which will | ||
| 103 | result in abnormal termination. | ||
| 104 | */ | ||
| 105 | int | ||
| 106 | main (int argc, char *argv[]) | ||
| 107 | { | ||
| 108 | int n; | ||
| 109 | |||
| 110 | n = argc > 1 ? atoi (argv[1]) : 0; | ||
| 111 | bool is_at_root = (n == 0); | ||
| 112 | if (is_at_root) | ||
| 113 | msg ("begin"); | ||
| 114 | |||
| 115 | /* If -k is passed, crash this process. */ | ||
| 116 | if (argc > 2 && !strcmp(argv[2], "-k")) | ||
| 117 | { | ||
| 118 | consume_some_resources_and_die (n); | ||
| 119 | NOT_REACHED (); | ||
| 120 | } | ||
| 121 | |||
| 122 | int howmany = is_at_root ? EXPECTED_REPETITIONS : 1; | ||
| 123 | int i, expected_depth = -1; | ||
| 124 | |||
| 125 | for (i = 0; i < howmany; i++) | ||
| 126 | { | ||
| 127 | pid_t child_pid; | ||
| 128 | |||
| 129 | /* Spawn a child that will be abnormally terminated. | ||
| 130 | To speed the test up, do this only for processes | ||
| 131 | spawned at a certain depth. */ | ||
| 132 | if (n > EXPECTED_DEPTH_TO_PASS/2) | ||
| 133 | { | ||
| 134 | child_pid = spawn_child (n + 1, CRASH); | ||
| 135 | if (child_pid != -1) | ||
| 136 | { | ||
| 137 | if (wait (child_pid) != -1) | ||
| 138 | fail ("crashed child should return -1."); | ||
| 139 | } | ||
| 140 | /* If spawning this child failed, so should | ||
| 141 | the next spawn_child below. */ | ||
| 142 | } | ||
| 143 | |||
| 144 | /* Now spawn the child that will recurse. */ | ||
| 145 | child_pid = spawn_child (n + 1, RECURSE); | ||
| 146 | |||
| 147 | /* If maximum depth is reached, return result. */ | ||
| 148 | if (child_pid == -1) | ||
| 149 | return n; | ||
| 150 | |||
| 151 | /* Else wait for child to report how deeply it was able to recurse. */ | ||
| 152 | int reached_depth = wait (child_pid); | ||
| 153 | if (reached_depth == -1) | ||
| 154 | fail ("wait returned -1."); | ||
| 155 | |||
| 156 | /* Record the depth reached during the first run; on subsequent | ||
| 157 | runs, fail if those runs do not match the depth achieved on the | ||
| 158 | first run. */ | ||
| 159 | if (i == 0) | ||
| 160 | expected_depth = reached_depth; | ||
| 161 | else if (expected_depth != reached_depth) | ||
| 162 | fail ("after run %d/%d, expected depth %d, actual depth %d.", | ||
| 163 | i, howmany, expected_depth, reached_depth); | ||
| 164 | ASSERT (expected_depth == reached_depth); | ||
| 165 | } | ||
| 166 | |||
| 167 | consume_some_resources (); | ||
| 168 | |||
| 169 | if (n == 0) | ||
| 170 | { | ||
| 171 | if (expected_depth < EXPECTED_DEPTH_TO_PASS) | ||
| 172 | fail ("should have forked at least %d times.", EXPECTED_DEPTH_TO_PASS); | ||
| 173 | msg ("success. program forked %d times.", howmany); | ||
| 174 | msg ("end"); | ||
| 175 | } | ||
| 176 | |||
| 177 | return expected_depth; | ||
| 178 | } | ||
| 179 | // vim: sw=2 | ||
diff --git a/pintos-progos/tests/userprog/no-vm/multi-oom.ck b/pintos-progos/tests/userprog/no-vm/multi-oom.ck new file mode 100644 index 0000000..59a0bcd --- /dev/null +++ b/pintos-progos/tests/userprog/no-vm/multi-oom.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected (IGNORE_USER_FAULTS => 1, IGNORE_EXIT_CODES => 1, [<<'EOF']); | ||
| 6 | (multi-oom) begin | ||
| 7 | (multi-oom) success. program forked 10 times. | ||
| 8 | (multi-oom) end | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/userprog/null.ck b/pintos-progos/tests/userprog/null.ck new file mode 100644 index 0000000..980de35 --- /dev/null +++ b/pintos-progos/tests/userprog/null.ck | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | system call! | ||
| 7 | EOF | ||
| 8 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-bad-ptr.c b/pintos-progos/tests/userprog/open-bad-ptr.c new file mode 100644 index 0000000..9cd4edf --- /dev/null +++ b/pintos-progos/tests/userprog/open-bad-ptr.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* Passes an invalid pointer to the open system call. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | msg ("open(0x20101234): %d", open ((char *) 0x20101234)); | ||
| 12 | fail ("should have called exit(-1)"); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/open-bad-ptr.ck b/pintos-progos/tests/userprog/open-bad-ptr.ck new file mode 100644 index 0000000..45349e2 --- /dev/null +++ b/pintos-progos/tests/userprog/open-bad-ptr.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (open-bad-ptr) begin | ||
| 7 | (open-bad-ptr) end | ||
| 8 | open-bad-ptr: exit(0) | ||
| 9 | EOF | ||
| 10 | (open-bad-ptr) begin | ||
| 11 | open-bad-ptr: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-boundary.c b/pintos-progos/tests/userprog/open-boundary.c new file mode 100644 index 0000000..cc8ff8b --- /dev/null +++ b/pintos-progos/tests/userprog/open-boundary.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Creates a file whose name spans the boundary between two pages. | ||
| 2 | This is valid, so it must succeed. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/userprog/boundary.h" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | CHECK (open (copy_string_across_boundary ("sample.txt")) > 1, | ||
| 13 | "open \"sample.txt\""); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/open-boundary.ck b/pintos-progos/tests/userprog/open-boundary.ck new file mode 100644 index 0000000..8060d22 --- /dev/null +++ b/pintos-progos/tests/userprog/open-boundary.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (open-boundary) begin | ||
| 7 | (open-boundary) open "sample.txt" | ||
| 8 | (open-boundary) end | ||
| 9 | open-boundary: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-empty.c b/pintos-progos/tests/userprog/open-empty.c new file mode 100644 index 0000000..3ea9907 --- /dev/null +++ b/pintos-progos/tests/userprog/open-empty.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* Tries to open a file with the empty string as its name. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle = open (""); | ||
| 11 | if (handle != -1) | ||
| 12 | fail ("open() returned %d instead of -1", handle); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/open-empty.ck b/pintos-progos/tests/userprog/open-empty.ck new file mode 100644 index 0000000..885fb41 --- /dev/null +++ b/pintos-progos/tests/userprog/open-empty.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (open-empty) begin | ||
| 7 | (open-empty) end | ||
| 8 | open-empty: exit(0) | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-missing.c b/pintos-progos/tests/userprog/open-missing.c new file mode 100644 index 0000000..13ecbda --- /dev/null +++ b/pintos-progos/tests/userprog/open-missing.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* Tries to open a nonexistent file. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle = open ("no-such-file"); | ||
| 11 | if (handle != -1) | ||
| 12 | fail ("open() returned %d", handle); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/open-missing.ck b/pintos-progos/tests/userprog/open-missing.ck new file mode 100644 index 0000000..d72d878 --- /dev/null +++ b/pintos-progos/tests/userprog/open-missing.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (open-missing) begin | ||
| 7 | (open-missing) end | ||
| 8 | open-missing: exit(0) | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-normal.c b/pintos-progos/tests/userprog/open-normal.c new file mode 100644 index 0000000..5132465 --- /dev/null +++ b/pintos-progos/tests/userprog/open-normal.c | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* Open a file. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | int handle = open ("sample.txt"); | ||
| 11 | if (handle < 2) | ||
| 12 | fail ("open() returned %d", handle); | ||
| 13 | } | ||
diff --git a/pintos-progos/tests/userprog/open-normal.ck b/pintos-progos/tests/userprog/open-normal.ck new file mode 100644 index 0000000..4f6c342 --- /dev/null +++ b/pintos-progos/tests/userprog/open-normal.ck | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (open-normal) begin | ||
| 7 | (open-normal) end | ||
| 8 | open-normal: exit(0) | ||
| 9 | EOF | ||
| 10 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-null.c b/pintos-progos/tests/userprog/open-null.c new file mode 100644 index 0000000..bb418b8 --- /dev/null +++ b/pintos-progos/tests/userprog/open-null.c | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* Tries to open a file with the null pointer as its name. | ||
| 2 | The process must be terminated with exit code -1. */ | ||
| 3 | |||
| 4 | #include <stddef.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | open (NULL); | ||
| 12 | } | ||
diff --git a/pintos-progos/tests/userprog/open-null.ck b/pintos-progos/tests/userprog/open-null.ck new file mode 100644 index 0000000..b4a3bcb --- /dev/null +++ b/pintos-progos/tests/userprog/open-null.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (open-null) begin | ||
| 7 | (open-null) end | ||
| 8 | open-null: exit(0) | ||
| 9 | EOF | ||
| 10 | (open-null) begin | ||
| 11 | open-null: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/open-twice.c b/pintos-progos/tests/userprog/open-twice.c new file mode 100644 index 0000000..dd333af --- /dev/null +++ b/pintos-progos/tests/userprog/open-twice.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Tries to open the same file twice, | ||
| 2 | which must succeed and must return a different file descriptor | ||
| 3 | in each case. */ | ||
| 4 | |||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | int h1 = open ("sample.txt"); | ||
| 13 | int h2 = open ("sample.txt"); | ||
| 14 | |||
| 15 | CHECK ((h1 = open ("sample.txt")) > 1, "open \"sample.txt\" once"); | ||
| 16 | CHECK ((h2 = open ("sample.txt")) > 1, "open \"sample.txt\" again"); | ||
| 17 | if (h1 == h2) | ||
| 18 | fail ("open() returned %d both times", h1); | ||
| 19 | } | ||
diff --git a/pintos-progos/tests/userprog/open-twice.ck b/pintos-progos/tests/userprog/open-twice.ck new file mode 100644 index 0000000..64fa805 --- /dev/null +++ b/pintos-progos/tests/userprog/open-twice.ck | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (open-twice) begin | ||
| 7 | (open-twice) open "sample.txt" once | ||
| 8 | (open-twice) open "sample.txt" again | ||
| 9 | (open-twice) end | ||
| 10 | open-twice: exit(0) | ||
| 11 | EOF | ||
| 12 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-bad-fd.c b/pintos-progos/tests/userprog/read-bad-fd.c new file mode 100644 index 0000000..a8b190d --- /dev/null +++ b/pintos-progos/tests/userprog/read-bad-fd.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Tries to read from an invalid fd, | ||
| 2 | which must either fail silently or terminate the process with | ||
| 3 | exit code -1. */ | ||
| 4 | |||
| 5 | #include <limits.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | char buf; | ||
| 14 | read (0x20101234, &buf, 1); | ||
| 15 | read (5, &buf, 1); | ||
| 16 | read (1234, &buf, 1); | ||
| 17 | read (-1, &buf, 1); | ||
| 18 | read (-1024, &buf, 1); | ||
| 19 | read (INT_MIN, &buf, 1); | ||
| 20 | read (INT_MAX, &buf, 1); | ||
| 21 | } | ||
diff --git a/pintos-progos/tests/userprog/read-bad-fd.ck b/pintos-progos/tests/userprog/read-bad-fd.ck new file mode 100644 index 0000000..5fedcc7 --- /dev/null +++ b/pintos-progos/tests/userprog/read-bad-fd.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (read-bad-fd) begin | ||
| 7 | (read-bad-fd) end | ||
| 8 | read-bad-fd: exit(0) | ||
| 9 | EOF | ||
| 10 | (read-bad-fd) begin | ||
| 11 | read-bad-fd: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-bad-ptr.c b/pintos-progos/tests/userprog/read-bad-ptr.c new file mode 100644 index 0000000..8fe756e --- /dev/null +++ b/pintos-progos/tests/userprog/read-bad-ptr.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Passes an invalid pointer to the read system call. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle; | ||
| 12 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 13 | |||
| 14 | read (handle, (char *) 0xc0100000, 123); | ||
| 15 | fail ("should not have survived read()"); | ||
| 16 | } | ||
diff --git a/pintos-progos/tests/userprog/read-bad-ptr.ck b/pintos-progos/tests/userprog/read-bad-ptr.ck new file mode 100644 index 0000000..d10accf --- /dev/null +++ b/pintos-progos/tests/userprog/read-bad-ptr.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (read-bad-ptr) begin | ||
| 7 | (read-bad-ptr) open "sample.txt" | ||
| 8 | (read-bad-ptr) end | ||
| 9 | read-bad-ptr: exit(0) | ||
| 10 | EOF | ||
| 11 | (read-bad-ptr) begin | ||
| 12 | (read-bad-ptr) open "sample.txt" | ||
| 13 | read-bad-ptr: exit(-1) | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-boundary.c b/pintos-progos/tests/userprog/read-boundary.c new file mode 100644 index 0000000..9c19966 --- /dev/null +++ b/pintos-progos/tests/userprog/read-boundary.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* Reads data spanning two pages in virtual address space, | ||
| 2 | which must succeed. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/userprog/boundary.h" | ||
| 7 | #include "tests/userprog/sample.inc" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | int handle; | ||
| 15 | int byte_cnt; | ||
| 16 | char *buffer; | ||
| 17 | |||
| 18 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 19 | |||
| 20 | buffer = get_boundary_area () - sizeof sample / 2; | ||
| 21 | byte_cnt = read (handle, buffer, sizeof sample - 1); | ||
| 22 | if (byte_cnt != sizeof sample - 1) | ||
| 23 | fail ("read() returned %d instead of %zu", byte_cnt, sizeof sample - 1); | ||
| 24 | else if (strcmp (sample, buffer)) | ||
| 25 | { | ||
| 26 | msg ("expected text:\n%s", sample); | ||
| 27 | msg ("text actually read:\n%s", buffer); | ||
| 28 | fail ("expected text differs from actual"); | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/pintos-progos/tests/userprog/read-boundary.ck b/pintos-progos/tests/userprog/read-boundary.ck new file mode 100644 index 0000000..08dc161 --- /dev/null +++ b/pintos-progos/tests/userprog/read-boundary.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (read-boundary) begin | ||
| 7 | (read-boundary) open "sample.txt" | ||
| 8 | (read-boundary) end | ||
| 9 | read-boundary: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-normal.c b/pintos-progos/tests/userprog/read-normal.c new file mode 100644 index 0000000..16d15cc --- /dev/null +++ b/pintos-progos/tests/userprog/read-normal.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Try reading a file in the most normal way. */ | ||
| 2 | |||
| 3 | #include "tests/userprog/sample.inc" | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | check_file ("sample.txt", sample, sizeof sample - 1); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/read-normal.ck b/pintos-progos/tests/userprog/read-normal.ck new file mode 100644 index 0000000..0ed2998 --- /dev/null +++ b/pintos-progos/tests/userprog/read-normal.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (read-normal) begin | ||
| 7 | (read-normal) open "sample.txt" for verification | ||
| 8 | (read-normal) verified contents of "sample.txt" | ||
| 9 | (read-normal) close "sample.txt" | ||
| 10 | (read-normal) end | ||
| 11 | read-normal: exit(0) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-stdout.c b/pintos-progos/tests/userprog/read-stdout.c new file mode 100644 index 0000000..d0630b9 --- /dev/null +++ b/pintos-progos/tests/userprog/read-stdout.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Try reading from fd 1 (stdout), | ||
| 2 | which may just fail or terminate the process with -1 exit | ||
| 3 | code. */ | ||
| 4 | |||
| 5 | #include <stdio.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | char buf; | ||
| 13 | read (STDOUT_FILENO, &buf, 1); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/read-stdout.ck b/pintos-progos/tests/userprog/read-stdout.ck new file mode 100644 index 0000000..7d87b52 --- /dev/null +++ b/pintos-progos/tests/userprog/read-stdout.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (read-stdout) begin | ||
| 7 | (read-stdout) end | ||
| 8 | read-stdout: exit(0) | ||
| 9 | EOF | ||
| 10 | (read-stdout) begin | ||
| 11 | read-stdout: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/read-zero.c b/pintos-progos/tests/userprog/read-zero.c new file mode 100644 index 0000000..e441817 --- /dev/null +++ b/pintos-progos/tests/userprog/read-zero.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* Try a 0-byte read, which should return 0 without reading | ||
| 2 | anything. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle, byte_cnt; | ||
| 12 | char buf; | ||
| 13 | |||
| 14 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 15 | |||
| 16 | buf = 123; | ||
| 17 | byte_cnt = read (handle, &buf, 0); | ||
| 18 | if (byte_cnt != 0) | ||
| 19 | fail ("read() returned %d instead of 0", byte_cnt); | ||
| 20 | else if (buf != 123) | ||
| 21 | fail ("0-byte read() modified buffer"); | ||
| 22 | } | ||
diff --git a/pintos-progos/tests/userprog/read-zero.ck b/pintos-progos/tests/userprog/read-zero.ck new file mode 100644 index 0000000..8346dbc --- /dev/null +++ b/pintos-progos/tests/userprog/read-zero.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (read-zero) begin | ||
| 7 | (read-zero) open "sample.txt" | ||
| 8 | (read-zero) end | ||
| 9 | read-zero: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/rox-child.c b/pintos-progos/tests/userprog/rox-child.c new file mode 100644 index 0000000..30afba2 --- /dev/null +++ b/pintos-progos/tests/userprog/rox-child.c | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | /* Ensure that the executable of a running process cannot be | ||
| 2 | modified, even by a child process. */ | ||
| 3 | |||
| 4 | #define CHILD_CNT "1" | ||
| 5 | #include "tests/userprog/rox-child.inc" | ||
diff --git a/pintos-progos/tests/userprog/rox-child.ck b/pintos-progos/tests/userprog/rox-child.ck new file mode 100644 index 0000000..e6363fb --- /dev/null +++ b/pintos-progos/tests/userprog/rox-child.ck | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (rox-child) begin | ||
| 7 | (rox-child) open "child-rox" | ||
| 8 | (rox-child) read "child-rox" | ||
| 9 | (rox-child) write "child-rox" | ||
| 10 | (rox-child) exec "child-rox 1" | ||
| 11 | (child-rox) begin | ||
| 12 | (child-rox) try to write "child-rox" | ||
| 13 | (child-rox) try to write "child-rox" | ||
| 14 | (child-rox) end | ||
| 15 | child-rox: exit(12) | ||
| 16 | (rox-child) write "child-rox" | ||
| 17 | (rox-child) end | ||
| 18 | rox-child: exit(0) | ||
| 19 | EOF | ||
| 20 | pass; | ||
diff --git a/pintos-progos/tests/userprog/rox-child.inc b/pintos-progos/tests/userprog/rox-child.inc new file mode 100644 index 0000000..1e2ade9 --- /dev/null +++ b/pintos-progos/tests/userprog/rox-child.inc | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* -*- c -*- */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | const char *child_cmd = "child-rox " CHILD_CNT; | ||
| 11 | int handle; | ||
| 12 | pid_t child; | ||
| 13 | char buffer[16]; | ||
| 14 | |||
| 15 | /* Open child-rox, read from it, write back same data. */ | ||
| 16 | CHECK ((handle = open ("child-rox")) > 1, "open \"child-rox\""); | ||
| 17 | CHECK (read (handle, buffer, sizeof buffer) == (int) sizeof buffer, | ||
| 18 | "read \"child-rox\""); | ||
| 19 | seek (handle, 0); | ||
| 20 | CHECK (write (handle, buffer, sizeof buffer) == (int) sizeof buffer, | ||
| 21 | "write \"child-rox\""); | ||
| 22 | |||
| 23 | /* Execute child-rox and wait for it. */ | ||
| 24 | CHECK ((child = exec (child_cmd)) != -1, "exec \"%s\"", child_cmd); | ||
| 25 | quiet = true; | ||
| 26 | CHECK (wait (child) == 12, "wait for child"); | ||
| 27 | quiet = false; | ||
| 28 | |||
| 29 | /* Write to child-rox again. */ | ||
| 30 | seek (handle, 0); | ||
| 31 | CHECK (write (handle, buffer, sizeof buffer) == (int) sizeof buffer, | ||
| 32 | "write \"child-rox\""); | ||
| 33 | } | ||
diff --git a/pintos-progos/tests/userprog/rox-multichild.c b/pintos-progos/tests/userprog/rox-multichild.c new file mode 100644 index 0000000..8e74dab --- /dev/null +++ b/pintos-progos/tests/userprog/rox-multichild.c | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | /* Ensure that the executable of a running process cannot be | ||
| 2 | modified, even in the presence of multiple children. */ | ||
| 3 | |||
| 4 | #define CHILD_CNT "5" | ||
| 5 | #include "tests/userprog/rox-child.inc" | ||
diff --git a/pintos-progos/tests/userprog/rox-multichild.ck b/pintos-progos/tests/userprog/rox-multichild.ck new file mode 100644 index 0000000..14b27db --- /dev/null +++ b/pintos-progos/tests/userprog/rox-multichild.ck | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (rox-multichild) begin | ||
| 7 | (rox-multichild) open "child-rox" | ||
| 8 | (rox-multichild) read "child-rox" | ||
| 9 | (rox-multichild) write "child-rox" | ||
| 10 | (rox-multichild) exec "child-rox 5" | ||
| 11 | (child-rox) begin | ||
| 12 | (child-rox) try to write "child-rox" | ||
| 13 | (child-rox) exec "child-rox 4" | ||
| 14 | (child-rox) begin | ||
| 15 | (child-rox) try to write "child-rox" | ||
| 16 | (child-rox) exec "child-rox 3" | ||
| 17 | (child-rox) begin | ||
| 18 | (child-rox) try to write "child-rox" | ||
| 19 | (child-rox) exec "child-rox 2" | ||
| 20 | (child-rox) begin | ||
| 21 | (child-rox) try to write "child-rox" | ||
| 22 | (child-rox) exec "child-rox 1" | ||
| 23 | (child-rox) begin | ||
| 24 | (child-rox) try to write "child-rox" | ||
| 25 | (child-rox) try to write "child-rox" | ||
| 26 | (child-rox) end | ||
| 27 | child-rox: exit(12) | ||
| 28 | (child-rox) try to write "child-rox" | ||
| 29 | (child-rox) end | ||
| 30 | child-rox: exit(12) | ||
| 31 | (child-rox) try to write "child-rox" | ||
| 32 | (child-rox) end | ||
| 33 | child-rox: exit(12) | ||
| 34 | (child-rox) try to write "child-rox" | ||
| 35 | (child-rox) end | ||
| 36 | child-rox: exit(12) | ||
| 37 | (child-rox) try to write "child-rox" | ||
| 38 | (child-rox) end | ||
| 39 | child-rox: exit(12) | ||
| 40 | (rox-multichild) write "child-rox" | ||
| 41 | (rox-multichild) end | ||
| 42 | rox-multichild: exit(0) | ||
| 43 | EOF | ||
| 44 | pass; | ||
diff --git a/pintos-progos/tests/userprog/rox-simple.c b/pintos-progos/tests/userprog/rox-simple.c new file mode 100644 index 0000000..e84a064 --- /dev/null +++ b/pintos-progos/tests/userprog/rox-simple.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Ensure that the executable of a running process cannot be | ||
| 2 | modified. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle; | ||
| 12 | char buffer[16]; | ||
| 13 | |||
| 14 | CHECK ((handle = open ("rox-simple")) > 1, "open \"rox-simple\""); | ||
| 15 | CHECK (read (handle, buffer, sizeof buffer) == (int) sizeof buffer, | ||
| 16 | "read \"rox-simple\""); | ||
| 17 | CHECK (write (handle, buffer, sizeof buffer) == 0, | ||
| 18 | "try to write \"rox-simple\""); | ||
| 19 | } | ||
diff --git a/pintos-progos/tests/userprog/rox-simple.ck b/pintos-progos/tests/userprog/rox-simple.ck new file mode 100644 index 0000000..c9dcc66 --- /dev/null +++ b/pintos-progos/tests/userprog/rox-simple.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (rox-simple) begin | ||
| 7 | (rox-simple) open "rox-simple" | ||
| 8 | (rox-simple) read "rox-simple" | ||
| 9 | (rox-simple) try to write "rox-simple" | ||
| 10 | (rox-simple) end | ||
| 11 | rox-simple: exit(0) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/sample.inc b/pintos-progos/tests/userprog/sample.inc new file mode 100644 index 0000000..59f2bcb --- /dev/null +++ b/pintos-progos/tests/userprog/sample.inc | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | char sample[] = { | ||
| 2 | "\"Amazing Electronic Fact: If you scuffed your feet long enough without\n" | ||
| 3 | " touching anything, you would build up so many electrons that your\n" | ||
| 4 | " finger would explode! But this is nothing to worry about unless you\n" | ||
| 5 | " have carpeting.\" --Dave Barry\n" | ||
| 6 | }; | ||
diff --git a/pintos-progos/tests/userprog/sample.txt b/pintos-progos/tests/userprog/sample.txt new file mode 100644 index 0000000..5050fec --- /dev/null +++ b/pintos-progos/tests/userprog/sample.txt | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | "Amazing Electronic Fact: If you scuffed your feet long enough without | ||
| 2 | touching anything, you would build up so many electrons that your | ||
| 3 | finger would explode! But this is nothing to worry about unless you | ||
| 4 | have carpeting." --Dave Barry | ||
diff --git a/pintos-progos/tests/userprog/sc-bad-arg.c b/pintos-progos/tests/userprog/sc-bad-arg.c new file mode 100644 index 0000000..0b512a0 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-bad-arg.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* Sticks a system call number (SYS_EXIT) at the very top of the | ||
| 2 | stack, then invokes a system call with the stack pointer | ||
| 3 | (%esp) set to its address. The process must be terminated | ||
| 4 | with -1 exit code because the argument to the system call | ||
| 5 | would be above the top of the user address space. */ | ||
| 6 | |||
| 7 | #include <syscall-nr.h> | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | asm volatile ("movl $0xbffffffc, %%esp; movl %0, (%%esp); int $0x30" | ||
| 15 | : : "i" (SYS_EXIT)); | ||
| 16 | fail ("should have called exit(-1)"); | ||
| 17 | } | ||
diff --git a/pintos-progos/tests/userprog/sc-bad-arg.ck b/pintos-progos/tests/userprog/sc-bad-arg.ck new file mode 100644 index 0000000..8981105 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-bad-arg.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (sc-bad-arg) begin | ||
| 7 | sc-bad-arg: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/sc-bad-sp.c b/pintos-progos/tests/userprog/sc-bad-sp.c new file mode 100644 index 0000000..39cce84 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-bad-sp.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Invokes a system call with the stack pointer (%esp) set to a | ||
| 2 | bad address. The process must be terminated with -1 exit | ||
| 3 | code. | ||
| 4 | |||
| 5 | For Project 3: The bad address lies approximately 64MB below | ||
| 6 | the code segment, so there is no ambiguity that this attempt | ||
| 7 | must be rejected even after stack growth is implemented. | ||
| 8 | Moreover, a good stack growth heuristics should probably not | ||
| 9 | grow the stack for the purpose of reading the system call | ||
| 10 | number and arguments. */ | ||
| 11 | |||
| 12 | #include "tests/lib.h" | ||
| 13 | #include "tests/main.h" | ||
| 14 | |||
| 15 | void | ||
| 16 | test_main (void) | ||
| 17 | { | ||
| 18 | asm volatile ("movl $.-(64*1024*1024), %esp; int $0x30"); | ||
| 19 | fail ("should have called exit(-1)"); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/userprog/sc-bad-sp.ck b/pintos-progos/tests/userprog/sc-bad-sp.ck new file mode 100644 index 0000000..498cec1 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-bad-sp.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (sc-bad-sp) begin | ||
| 7 | sc-bad-sp: exit(-1) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/sc-boundary-2.c b/pintos-progos/tests/userprog/sc-boundary-2.c new file mode 100644 index 0000000..8acf036 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-boundary-2.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* Invokes a system call with one byte of the system call's | ||
| 2 | argument on a separate page from the rest of the bytes. This | ||
| 3 | must work. */ | ||
| 4 | |||
| 5 | #include <syscall-nr.h> | ||
| 6 | #include "tests/userprog/boundary.h" | ||
| 7 | #include "tests/lib.h" | ||
| 8 | #include "tests/main.h" | ||
| 9 | |||
| 10 | void | ||
| 11 | test_main (void) | ||
| 12 | { | ||
| 13 | /* Make one byte of a syscall argument hang over into a second | ||
| 14 | page. */ | ||
| 15 | int *p = (int *) ((char *) get_boundary_area () - 7); | ||
| 16 | p[0] = SYS_EXIT; | ||
| 17 | p[1] = 67; | ||
| 18 | |||
| 19 | /* Invoke the system call. */ | ||
| 20 | asm volatile ("movl %0, %%esp; int $0x30" : : "g" (p)); | ||
| 21 | fail ("should have called exit(67)"); | ||
| 22 | } | ||
diff --git a/pintos-progos/tests/userprog/sc-boundary-2.ck b/pintos-progos/tests/userprog/sc-boundary-2.ck new file mode 100644 index 0000000..43766bf --- /dev/null +++ b/pintos-progos/tests/userprog/sc-boundary-2.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (sc-boundary-2) begin | ||
| 7 | sc-boundary-2: exit(67) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/sc-boundary.c b/pintos-progos/tests/userprog/sc-boundary.c new file mode 100644 index 0000000..d889535 --- /dev/null +++ b/pintos-progos/tests/userprog/sc-boundary.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* Invokes a system call with the system call number and its | ||
| 2 | argument on separate pages. This must work. */ | ||
| 3 | |||
| 4 | #include <syscall-nr.h> | ||
| 5 | #include "tests/userprog/boundary.h" | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | /* Put a syscall number at the end of one page | ||
| 13 | and its argument at the beginning of another. */ | ||
| 14 | int *p = get_boundary_area (); | ||
| 15 | p--; | ||
| 16 | p[0] = SYS_EXIT; | ||
| 17 | p[1] = 42; | ||
| 18 | |||
| 19 | /* Invoke the system call. */ | ||
| 20 | asm volatile ("movl %0, %%esp; int $0x30" : : "g" (p)); | ||
| 21 | fail ("should have called exit(42)"); | ||
| 22 | } | ||
diff --git a/pintos-progos/tests/userprog/sc-boundary.ck b/pintos-progos/tests/userprog/sc-boundary.ck new file mode 100644 index 0000000..3f7cbaf --- /dev/null +++ b/pintos-progos/tests/userprog/sc-boundary.ck | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (sc-boundary) begin | ||
| 7 | sc-boundary: exit(42) | ||
| 8 | EOF | ||
| 9 | pass; | ||
diff --git a/pintos-progos/tests/userprog/wait-bad-pid.c b/pintos-progos/tests/userprog/wait-bad-pid.c new file mode 100644 index 0000000..3fe8ee4 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-bad-pid.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Waits for an invalid pid. This may fail or terminate the | ||
| 2 | process with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | wait ((pid_t) 0x0c020301); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/wait-bad-pid.ck b/pintos-progos/tests/userprog/wait-bad-pid.ck new file mode 100644 index 0000000..db63fb9 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-bad-pid.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (wait-bad-pid) begin | ||
| 7 | (wait-bad-pid) end | ||
| 8 | wait-bad-pid: exit(0) | ||
| 9 | EOF | ||
| 10 | (wait-bad-pid) begin | ||
| 11 | wait-bad-pid: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/wait-killed.c b/pintos-progos/tests/userprog/wait-killed.c new file mode 100644 index 0000000..6a2a6b5 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-killed.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Wait for a process that will be killed for bad behavior. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("wait(exec()) = %d", wait (exec ("child-bad"))); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/wait-killed.ck b/pintos-progos/tests/userprog/wait-killed.ck new file mode 100644 index 0000000..5df0e9c --- /dev/null +++ b/pintos-progos/tests/userprog/wait-killed.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (wait-killed) begin | ||
| 7 | (child-bad) begin | ||
| 8 | child-bad: exit(-1) | ||
| 9 | (wait-killed) wait(exec()) = -1 | ||
| 10 | (wait-killed) end | ||
| 11 | wait-killed: exit(0) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/wait-simple.c b/pintos-progos/tests/userprog/wait-simple.c new file mode 100644 index 0000000..d3afcf3 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-simple.c | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /* Wait for a subprocess to finish. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/lib.h" | ||
| 5 | #include "tests/main.h" | ||
| 6 | |||
| 7 | void | ||
| 8 | test_main (void) | ||
| 9 | { | ||
| 10 | msg ("wait(exec()) = %d", wait (exec ("child-simple"))); | ||
| 11 | } | ||
diff --git a/pintos-progos/tests/userprog/wait-simple.ck b/pintos-progos/tests/userprog/wait-simple.ck new file mode 100644 index 0000000..93dd577 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-simple.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (wait-simple) begin | ||
| 7 | (child-simple) run | ||
| 8 | child-simple: exit(81) | ||
| 9 | (wait-simple) wait(exec()) = 81 | ||
| 10 | (wait-simple) end | ||
| 11 | wait-simple: exit(0) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/wait-twice.c b/pintos-progos/tests/userprog/wait-twice.c new file mode 100644 index 0000000..785e684 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-twice.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* Wait for a subprocess to finish, twice. | ||
| 2 | The first call must wait in the usual way and return the exit code. | ||
| 3 | The second wait call must return -1 immediately. */ | ||
| 4 | |||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | pid_t child = exec ("child-simple"); | ||
| 13 | msg ("wait(exec()) = %d", wait (child)); | ||
| 14 | msg ("wait(exec()) = %d", wait (child)); | ||
| 15 | } | ||
diff --git a/pintos-progos/tests/userprog/wait-twice.ck b/pintos-progos/tests/userprog/wait-twice.ck new file mode 100644 index 0000000..6d53843 --- /dev/null +++ b/pintos-progos/tests/userprog/wait-twice.ck | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (wait-twice) begin | ||
| 7 | (child-simple) run | ||
| 8 | child-simple: exit(81) | ||
| 9 | (wait-twice) wait(exec()) = 81 | ||
| 10 | (wait-twice) wait(exec()) = -1 | ||
| 11 | (wait-twice) end | ||
| 12 | wait-twice: exit(0) | ||
| 13 | EOF | ||
| 14 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-bad-fd.c b/pintos-progos/tests/userprog/write-bad-fd.c new file mode 100644 index 0000000..f3b1151 --- /dev/null +++ b/pintos-progos/tests/userprog/write-bad-fd.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Tries to write to an invalid fd, | ||
| 2 | which must either fail silently or terminate the process with | ||
| 3 | exit code -1. */ | ||
| 4 | |||
| 5 | #include <limits.h> | ||
| 6 | #include <syscall.h> | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | char buf = 123; | ||
| 13 | write (0x01012342, &buf, 1); | ||
| 14 | write (7, &buf, 1); | ||
| 15 | write (2546, &buf, 1); | ||
| 16 | write (-5, &buf, 1); | ||
| 17 | write (-8192, &buf, 1); | ||
| 18 | write (INT_MIN + 1, &buf, 1); | ||
| 19 | write (INT_MAX - 1, &buf, 1); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/userprog/write-bad-fd.ck b/pintos-progos/tests/userprog/write-bad-fd.ck new file mode 100644 index 0000000..8da7a8b --- /dev/null +++ b/pintos-progos/tests/userprog/write-bad-fd.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (write-bad-fd) begin | ||
| 7 | (write-bad-fd) end | ||
| 8 | write-bad-fd: exit(0) | ||
| 9 | EOF | ||
| 10 | (write-bad-fd) begin | ||
| 11 | write-bad-fd: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-bad-ptr.c b/pintos-progos/tests/userprog/write-bad-ptr.c new file mode 100644 index 0000000..5336479 --- /dev/null +++ b/pintos-progos/tests/userprog/write-bad-ptr.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* Passes an invalid pointer to the write system call. | ||
| 2 | The process must be terminated with -1 exit code. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle; | ||
| 12 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 13 | |||
| 14 | write (handle, (char *) 0x10123420, 123); | ||
| 15 | fail ("should have exited with -1"); | ||
| 16 | } | ||
diff --git a/pintos-progos/tests/userprog/write-bad-ptr.ck b/pintos-progos/tests/userprog/write-bad-ptr.ck new file mode 100644 index 0000000..ad9f399 --- /dev/null +++ b/pintos-progos/tests/userprog/write-bad-ptr.ck | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (write-bad-ptr) begin | ||
| 7 | (write-bad-ptr) open "sample.txt" | ||
| 8 | (write-bad-ptr) end | ||
| 9 | write-bad-ptr: exit(0) | ||
| 10 | EOF | ||
| 11 | (write-bad-ptr) begin | ||
| 12 | (write-bad-ptr) open "sample.txt" | ||
| 13 | write-bad-ptr: exit(-1) | ||
| 14 | EOF | ||
| 15 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-boundary.c b/pintos-progos/tests/userprog/write-boundary.c new file mode 100644 index 0000000..d2de1d4 --- /dev/null +++ b/pintos-progos/tests/userprog/write-boundary.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* Writes data spanning two pages in virtual address space, | ||
| 2 | which must succeed. */ | ||
| 3 | |||
| 4 | #include <string.h> | ||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/userprog/boundary.h" | ||
| 7 | #include "tests/userprog/sample.inc" | ||
| 8 | #include "tests/lib.h" | ||
| 9 | #include "tests/main.h" | ||
| 10 | |||
| 11 | void | ||
| 12 | test_main (void) | ||
| 13 | { | ||
| 14 | int handle; | ||
| 15 | int byte_cnt; | ||
| 16 | char *sample_p; | ||
| 17 | |||
| 18 | sample_p = copy_string_across_boundary (sample); | ||
| 19 | |||
| 20 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 21 | |||
| 22 | byte_cnt = write (handle, sample_p, sizeof sample - 1); | ||
| 23 | if (byte_cnt != sizeof sample - 1) | ||
| 24 | fail ("write() returned %d instead of %zu", byte_cnt, sizeof sample - 1); | ||
| 25 | } | ||
diff --git a/pintos-progos/tests/userprog/write-boundary.ck b/pintos-progos/tests/userprog/write-boundary.ck new file mode 100644 index 0000000..7883781 --- /dev/null +++ b/pintos-progos/tests/userprog/write-boundary.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (write-boundary) begin | ||
| 7 | (write-boundary) open "sample.txt" | ||
| 8 | (write-boundary) end | ||
| 9 | write-boundary: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-normal.c b/pintos-progos/tests/userprog/write-normal.c new file mode 100644 index 0000000..e0297aa --- /dev/null +++ b/pintos-progos/tests/userprog/write-normal.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Try writing a file in the most normal way. */ | ||
| 2 | |||
| 3 | #include <syscall.h> | ||
| 4 | #include "tests/userprog/sample.inc" | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle, byte_cnt; | ||
| 12 | |||
| 13 | CHECK (create ("test.txt", sizeof sample - 1), "create \"test.txt\""); | ||
| 14 | CHECK ((handle = open ("test.txt")) > 1, "open \"test.txt\""); | ||
| 15 | |||
| 16 | byte_cnt = write (handle, sample, sizeof sample - 1); | ||
| 17 | if (byte_cnt != sizeof sample - 1) | ||
| 18 | fail ("write() returned %d instead of %zu", byte_cnt, sizeof sample - 1); | ||
| 19 | } | ||
| 20 | |||
diff --git a/pintos-progos/tests/userprog/write-normal.ck b/pintos-progos/tests/userprog/write-normal.ck new file mode 100644 index 0000000..9fa6024 --- /dev/null +++ b/pintos-progos/tests/userprog/write-normal.ck | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (write-normal) begin | ||
| 7 | (write-normal) create "test.txt" | ||
| 8 | (write-normal) open "test.txt" | ||
| 9 | (write-normal) end | ||
| 10 | write-normal: exit(0) | ||
| 11 | EOF | ||
| 12 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-stdin.c b/pintos-progos/tests/userprog/write-stdin.c new file mode 100644 index 0000000..491ea53 --- /dev/null +++ b/pintos-progos/tests/userprog/write-stdin.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* Try writing to fd 0 (stdin), | ||
| 2 | which may just fail or terminate the process with -1 exit | ||
| 3 | code. */ | ||
| 4 | |||
| 5 | #include <syscall.h> | ||
| 6 | #include "tests/lib.h" | ||
| 7 | #include "tests/main.h" | ||
| 8 | |||
| 9 | void | ||
| 10 | test_main (void) | ||
| 11 | { | ||
| 12 | char buf = 123; | ||
| 13 | write (0, &buf, 1); | ||
| 14 | } | ||
diff --git a/pintos-progos/tests/userprog/write-stdin.ck b/pintos-progos/tests/userprog/write-stdin.ck new file mode 100644 index 0000000..a6caf81 --- /dev/null +++ b/pintos-progos/tests/userprog/write-stdin.ck | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF', <<'EOF']); | ||
| 6 | (write-stdin) begin | ||
| 7 | (write-stdin) end | ||
| 8 | write-stdin: exit(0) | ||
| 9 | EOF | ||
| 10 | (write-stdin) begin | ||
| 11 | write-stdin: exit(-1) | ||
| 12 | EOF | ||
| 13 | pass; | ||
diff --git a/pintos-progos/tests/userprog/write-zero.c b/pintos-progos/tests/userprog/write-zero.c new file mode 100644 index 0000000..d8dac9b --- /dev/null +++ b/pintos-progos/tests/userprog/write-zero.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* Try a 0-byte write, which should return 0 without writing | ||
| 2 | anything. */ | ||
| 3 | |||
| 4 | #include <syscall.h> | ||
| 5 | #include "tests/lib.h" | ||
| 6 | #include "tests/main.h" | ||
| 7 | |||
| 8 | void | ||
| 9 | test_main (void) | ||
| 10 | { | ||
| 11 | int handle, byte_cnt; | ||
| 12 | char buf; | ||
| 13 | |||
| 14 | CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\""); | ||
| 15 | |||
| 16 | buf = 123; | ||
| 17 | byte_cnt = write (handle, &buf, 0); | ||
| 18 | if (byte_cnt != 0) | ||
| 19 | fail("write() returned %d instead of 0", byte_cnt); | ||
| 20 | } | ||
diff --git a/pintos-progos/tests/userprog/write-zero.ck b/pintos-progos/tests/userprog/write-zero.ck new file mode 100644 index 0000000..cc4cd60 --- /dev/null +++ b/pintos-progos/tests/userprog/write-zero.ck | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # -*- perl -*- | ||
| 2 | use strict; | ||
| 3 | use warnings; | ||
| 4 | use tests::tests; | ||
| 5 | check_expected ([<<'EOF']); | ||
| 6 | (write-zero) begin | ||
| 7 | (write-zero) open "sample.txt" | ||
| 8 | (write-zero) end | ||
| 9 | write-zero: exit(0) | ||
| 10 | EOF | ||
| 11 | pass; | ||
