diff --git a/userland/testbin/Makefile b/userland/testbin/Makefile index 44d1787..bfb4b03 100644 --- a/userland/testbin/Makefile +++ b/userland/testbin/Makefile @@ -11,7 +11,8 @@ SUBDIRS=add argtest badcall bigexec bigfile bigfork bigseek bloat conman \ malloctest matmult multiexec palin parallelvm poisondisk psort \ quinthuge quintmat quintsort randcall redirect rmdirtest rmtest \ sbrktest schedpong shll sink sort sparsefile spinner sty tail tictac \ - triplehuge triplemat triplesort usemtest waiter zero + triplehuge triplemat triplesort usemtest waiter zero \ + consoletest shelltest opentest readwritetest closetest # But not: # userthreads (no support in kernel API in base system) diff --git a/userland/testbin/add/add.c b/userland/testbin/add/add.c index 0af357e..edd680c 100644 --- a/userland/testbin/add/add.c +++ b/userland/testbin/add/add.c @@ -38,6 +38,7 @@ #include #include #include +#include int main(int argc, char *argv[]) @@ -52,6 +53,8 @@ main(int argc, char *argv[]) j = atoi(argv[2]); tprintf("Answer: %d\n", i+j); - + char buf[16]; + snprintf(buf, 16, "%d", i+j); + secprintf(SECRET, buf, "/testbin/add"); return 0; } diff --git a/userland/testbin/argtest/argtest.c b/userland/testbin/argtest/argtest.c index 4e28f8c..b805c59 100644 --- a/userland/testbin/argtest/argtest.c +++ b/userland/testbin/argtest/argtest.c @@ -36,6 +36,7 @@ */ #include +#include int main(int argc, char *argv[]) @@ -44,6 +45,9 @@ main(int argc, char *argv[]) int i; tprintf("argc: %d\n", argc); + char buf[16]; + snprintf(buf, 16, "argc: %d", argc); + secprintf(SECRET, buf, "/testbin/argtest"); for (i=0; i<=argc; i++) { tmp = argv[i]; @@ -51,6 +55,7 @@ main(int argc, char *argv[]) tmp = "[NULL]"; } tprintf("argv[%d]: %s\n", i, tmp); + secprintf(SECRET, tmp, "/testbin/argtest"); } return 0; diff --git a/userland/testbin/badcall/bad_chdir.c b/userland/testbin/badcall/bad_chdir.c index cf98845..7c555cc 100644 --- a/userland/testbin/badcall/bad_chdir.c +++ b/userland/testbin/badcall/bad_chdir.c @@ -38,7 +38,7 @@ #include "test.h" static -void +int chdir_empty(void) { int rv; @@ -49,13 +49,19 @@ chdir_empty(void) report_begin("chdir to empty string"); rv = chdir(""); - report_check2(rv, errno, EINVAL, 0); + return report_check2(rv, errno, EINVAL, 0); } void test_chdir(void) { - test_chdir_path(); - chdir_empty(); + int ntests = 0, result = 0, lost_points = 0; + test_chdir_path(&ntests, &lost_points); + + ntests++; + result = chdir_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-chdir", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_close.c b/userland/testbin/badcall/bad_close.c index 6d70e66..23aa833 100644 --- a/userland/testbin/badcall/bad_close.c +++ b/userland/testbin/badcall/bad_close.c @@ -36,5 +36,8 @@ void test_close(void) { - test_close_fd(); + int ntests = 0, lost_points = 0; + test_close_fd(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-close", ntests- lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_dup2.c b/userland/testbin/badcall/bad_dup2.c index db3a216..212e4b1 100644 --- a/userland/testbin/badcall/bad_dup2.c +++ b/userland/testbin/badcall/bad_dup2.c @@ -45,27 +45,29 @@ #include "test.h" static -void +int dup2_fd2(int fd, const char *desc) { - int rv; + int rv, failure; report_begin("%s", desc); rv = dup2(STDIN_FILENO, fd); - report_check(rv, errno, EBADF); + failure = report_check(rv, errno, EBADF); if (rv != -1) { close(fd); /* just in case */ } + return failure; } static -void +int dup2_self(void) { struct stat sb; int rv; int testfd; + int failure; /* use fd that isn't in use */ testfd = CLOSED_FD; @@ -75,22 +77,23 @@ dup2_self(void) rv = dup2(STDIN_FILENO, testfd); if (rv == -1) { report_result(rv, errno); - report_aborted(); - return; + report_aborted(&failure); + return failure; } report_begin("dup2 to same fd"); rv = dup2(testfd, testfd); if (rv == testfd) { - report_passed(); + report_passed(&failure); } else if (rv<0) { report_result(rv, errno); - report_failure(); + report_failure(&failure); } else { report_warnx("returned %d instead", rv); - report_failure(); + report_failure(&failure); + failure = FAILED; } report_begin("fstat fd after dup2 to itself"); @@ -100,43 +103,59 @@ dup2_self(void) } report_result(rv, errno); if (rv==0) { - report_passed(); + report_passed(&failure); } else if (errno != ENOSYS) { - report_failure(); + report_failure(&failure); } else { - report_skipped(); + report_skipped(&failure); /* no support for fstat; try lseek */ report_begin("lseek fd after dup2 to itself"); rv = lseek(testfd, 0, SEEK_CUR); report_result(rv, errno); if (rv==0 || (rv==-1 && errno==ESPIPE)) { - report_passed(); + report_passed(&failure); } else { - report_failure(); + report_failure(&failure); } } close(testfd); + return failure; } void test_dup2(void) { + int ntests = 0, failure, lost_points = 0; /* This does the first fd. */ - test_dup2_fd(); + test_dup2_fd(&ntests, &lost_points); /* Any interesting cases added here should also go in common_fds.c */ - dup2_fd2(-1, "dup2 to -1"); - dup2_fd2(-5, "dup2 to -5"); - dup2_fd2(IMPOSSIBLE_FD, "dup2 to impossible fd"); + ntests++; + failure = dup2_fd2(-1, "dup2 to -1"); + handle_result(failure, &lost_points); + + ntests++; + failure = dup2_fd2(-5, "dup2 to -5"); + handle_result(failure, &lost_points); + + ntests++; + failure = dup2_fd2(IMPOSSIBLE_FD, "dup2 to impossible fd"); + handle_result(failure, &lost_points); #ifdef OPEN_MAX - dup2_fd2(OPEN_MAX, "dup2 to OPEN_MAX"); + ntests++; + failure = dup2_fd2(OPEN_MAX, "dup2 to OPEN_MAX"); + handle_result(failure, &lost_points); #else warnx("Warning: OPEN_MAX not defined - test skipped"); #endif - dup2_self(); + ntests++; + failure = dup2_self(); + handle_result(failure, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-dup2", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_execv.c b/userland/testbin/badcall/bad_execv.c index 24ad1cb..06b3dc7 100644 --- a/userland/testbin/badcall/bad_execv.c +++ b/userland/testbin/badcall/bad_execv.c @@ -42,7 +42,7 @@ static int -exec_common_fork(void) +exec_common_fork(int *result) { int pid, rv, status, err; @@ -56,7 +56,7 @@ exec_common_fork(void) err = errno; report_begin("forking for test"); report_result(pid, err); - report_aborted(); + report_aborted(result); return -1; } @@ -70,10 +70,11 @@ exec_common_fork(void) err = errno; report_begin("waiting for test subprocess"); report_result(rv, err); - report_failure(); + report_failure(result); return -1; } if (WIFEXITED(status) && WEXITSTATUS(status) == MAGIC_STATUS) { + *result = SUCCESS; return 1; } /* Oops... */ @@ -84,98 +85,137 @@ exec_common_fork(void) else { report_warnx("exit %d", WEXITSTATUS(status)); } - report_failure(); + report_failure(result); return -1; } static -void +int exec_badprog(const void *prog, const char *desc) { int rv; + int result; char *args[2]; args[0] = (char *)"foo"; args[1] = NULL; - if (exec_common_fork() != 0) { - return; + if (exec_common_fork(&result) != 0) { + return result; } report_begin(desc); rv = execv(prog, args); - report_check(rv, errno, EFAULT); - exit(MAGIC_STATUS); + result = report_check(rv, errno, EFAULT); + //XXX: Make sure this doesn't interfere with SIGNALLED/EXITED + int code = MAGIC_STATUS | result; + exit(code); } static -void +int exec_emptyprog(void) { int rv; + int result; char *args[2]; args[0] = (char *)"foo"; args[1] = NULL; - if (exec_common_fork() != 0) { - return; + if (exec_common_fork(&result) != 0) { + return result; } report_begin("exec the empty string"); rv = execv("", args); - report_check2(rv, errno, EINVAL, EISDIR); - exit(MAGIC_STATUS); + result = report_check2(rv, errno, EINVAL, EISDIR); + //XXX: Make sure this doesn't interfere with SIGNALLED/EXITED + int code = MAGIC_STATUS | result; + exit(code); } static -void +int exec_badargs(void *args, const char *desc) { int rv; - - if (exec_common_fork() != 0) { - return; + int result; + if (exec_common_fork(&result) != 0) { + return result; } report_begin(desc); rv = execv("/bin/true", args); - report_check(rv, errno, EFAULT); - exit(MAGIC_STATUS); + result = report_check(rv, errno, EFAULT); + //XXX: Make sure this doesn't interfere with SIGNALLED/EXITED + int code = MAGIC_STATUS | result; + exit(code); } static -void +int exec_onearg(void *ptr, const char *desc) { int rv; + int result; char *args[3]; args[0] = (char *)"foo"; args[1] = (char *)ptr; args[2] = NULL; - if (exec_common_fork() != 0) { - return; + if (exec_common_fork(&result) != 0) { + return result; } report_begin(desc); rv = execv("/bin/true", args); - report_check(rv, errno, EFAULT); - exit(MAGIC_STATUS); + result = report_check(rv, errno, EFAULT); + //XXX: Make sure this doesn't interfere with SIGNALLED/EXITED + int code = MAGIC_STATUS | result; + exit(code); + } void test_execv(void) { - exec_badprog(NULL, "exec with NULL program"); - exec_badprog(INVAL_PTR, "exec with invalid pointer program"); - exec_badprog(KERN_PTR, "exec with kernel pointer program"); + int ntests = 0, result = 0, lost_points = 0; + ntests++; + result = exec_badprog(NULL, "exec with NULL program"); + handle_result(result, &lost_points); - exec_emptyprog(); + ntests++; + result = exec_badprog(INVAL_PTR, "exec with invalid pointer program"); + handle_result(result, &lost_points); - exec_badargs(NULL, "exec with NULL arglist"); - exec_badargs(INVAL_PTR, "exec with invalid pointer arglist"); - exec_badargs(KERN_PTR, "exec with kernel pointer arglist"); + ntests++; + result = exec_badprog(KERN_PTR, "exec with kernel pointer program"); + handle_result(result, &lost_points); - exec_onearg(INVAL_PTR, "exec with invalid pointer arg"); - exec_onearg(KERN_PTR, "exec with kernel pointer arg"); + ntests++; + result = exec_emptyprog(); + handle_result(result, &lost_points); + + ntests++; + result = exec_badargs(NULL, "exec with NULL arglist"); + handle_result(result, &lost_points); + + ntests++; + result = exec_badargs(INVAL_PTR, "exec with invalid pointer arglist"); + handle_result(result, &lost_points); + + ntests++; + result = exec_badargs(KERN_PTR, "exec with kernel pointer arglist"); + handle_result(result, &lost_points); + + + ntests++; + result = exec_onearg(INVAL_PTR, "exec with invalid pointer arg"); + handle_result(result, &lost_points); + + ntests++; + result = exec_onearg(KERN_PTR, "exec with kernel pointer arg"); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-execv", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_fsync.c b/userland/testbin/badcall/bad_fsync.c index fd67384..2d6d8a6 100644 --- a/userland/testbin/badcall/bad_fsync.c +++ b/userland/testbin/badcall/bad_fsync.c @@ -36,6 +36,10 @@ void test_fsync(void) { - test_fsync_fd(); + int ntests = 0, lost_points = 0; + + test_fsync_fd(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-fsync", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_ftruncate.c b/userland/testbin/badcall/bad_ftruncate.c index f88d7c8..114832f 100644 --- a/userland/testbin/badcall/bad_ftruncate.c +++ b/userland/testbin/badcall/bad_ftruncate.c @@ -44,52 +44,66 @@ #include "test.h" static -void +int ftruncate_fd_device(void) { int rv, fd; + int result; report_begin("ftruncate on device"); fd = open("null:", O_RDWR); if (fd<0) { report_warn("opening null: failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } rv = ftruncate(fd, 6); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); close(fd); + return result; } static -void +int ftruncate_size_neg(void) { int rv, fd; + int result; report_begin("ftruncate to negative size"); fd = open_testfile(NULL); if (fd<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } rv = ftruncate(fd, -60); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); close(fd); remove(TESTFILE); + return result; } void test_ftruncate(void) { - test_ftruncate_fd(); + int ntests = 0, lost_points = 0; + int result; - ftruncate_fd_device(); - ftruncate_size_neg(); + test_ftruncate_fd(&ntests, &lost_points); + + ntests++; + result = ftruncate_fd_device(); + handle_result(result, &lost_points); + + ntests++; + result = ftruncate_size_neg(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-ftruncate", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_getcwd.c b/userland/testbin/badcall/bad_getcwd.c index 4f94ba1..d6a2303 100644 --- a/userland/testbin/badcall/bad_getcwd.c +++ b/userland/testbin/badcall/bad_getcwd.c @@ -36,5 +36,8 @@ void test_getcwd(void) { - test_getcwd_buf(); + int ntests = 0, lost_points = 0; + test_getcwd_buf(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-getcwd", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_getdirentry.c b/userland/testbin/badcall/bad_getdirentry.c index 02806d2..34d39e8 100644 --- a/userland/testbin/badcall/bad_getdirentry.c +++ b/userland/testbin/badcall/bad_getdirentry.c @@ -36,6 +36,10 @@ void test_getdirentry(void) { - test_getdirentry_fd(); - test_getdirentry_buf(); + int ntests = 0, lost_points = 0; + + test_getdirentry_fd(&ntests, &lost_points); + test_getdirentry_buf(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-getdirentry", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_ioctl.c b/userland/testbin/badcall/bad_ioctl.c index 8ce38bc..a536429 100644 --- a/userland/testbin/badcall/bad_ioctl.c +++ b/userland/testbin/badcall/bad_ioctl.c @@ -41,30 +41,34 @@ #include "test.h" static -void +int one_ioctl_badbuf(int fd, int code, const char *codename, void *ptr, const char *ptrdesc) { int rv; + int result; report_begin("ioctl %s with %s", codename, ptrdesc); rv = ioctl(fd, code, ptr); - report_check(rv, errno, EFAULT); + result = report_check(rv, errno, EFAULT); + return result; } static -void +int any_ioctl_badbuf(int fd, int code, const char *codename) { - one_ioctl_badbuf(fd, code, codename, NULL, "NULL pointer"); - one_ioctl_badbuf(fd, code, codename, INVAL_PTR, "invalid pointer"); - one_ioctl_badbuf(fd, code, codename, KERN_PTR, "kernel pointer"); + int result; + result = one_ioctl_badbuf(fd, code, codename, NULL, "NULL pointer"); + result |= one_ioctl_badbuf(fd, code, codename, INVAL_PTR, "invalid pointer"); + result |= one_ioctl_badbuf(fd, code, codename, KERN_PTR, "kernel pointer"); + return result; } #define IOCTL(fd, sym) any_ioctl_badbuf(fd, sym, #sym) static -void +int ioctl_badbuf(void) { /* @@ -79,25 +83,38 @@ ioctl_badbuf(void) /* suppress gcc warning */ (void)any_ioctl_badbuf; + return 0; } static -void +int ioctl_badcode(void) { int rv; + int result; report_begin("invalid ioctl"); rv = ioctl(STDIN_FILENO, NONEXIST_IOCTL, NULL); - report_check(rv, errno, EIOCTL); + result = report_check(rv, errno, EIOCTL); + return result; } void test_ioctl(void) { - test_ioctl_fd(); + int ntests = 0, lost_points = 0; + int result; + + test_ioctl_fd(&ntests, &lost_points); /* Since we don't actually define any ioctls, this is not meaningful */ - ioctl_badcode(); - ioctl_badbuf(); + ntests++; + result = ioctl_badcode(); + handle_result(result, &lost_points); + + ntests++; + result = ioctl_badbuf(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-ioctl", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_link.c b/userland/testbin/badcall/bad_link.c index 63ecc15..80102f8 100644 --- a/userland/testbin/badcall/bad_link.c +++ b/userland/testbin/badcall/bad_link.c @@ -37,52 +37,69 @@ #include "test.h" static -void +int link_dir(void) { int rv; + int result; report_begin("hard link of ."); rv = link(".", TESTDIR); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); if (rv==0) { /* this might help recover... maybe */ remove(TESTDIR); } + return result; } static -void +int link_empty1(void) { int rv; report_begin("hard link of empty string"); rv = link("", TESTDIR); - report_check(rv, errno, EINVAL); + return report_check(rv, errno, EINVAL); } static -void +int link_empty2(void) { int rv; - + int result = FAILED; report_begin("hard link to empty string"); if (create_testdir()<0) { /*report_aborted();*/ /* XXX in create_testdir */ - return; + return result; } rv = link(TESTDIR, ""); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); rmdir(TESTDIR); + return result; } void test_link(void) { - test_link_paths(); - link_dir(); - link_empty1(); - link_empty2(); + int ntests = 0, lost_points = 0; + int result; + + test_link_paths(&ntests, &lost_points); + + ntests++; + result = link_dir(); + handle_result(result, &lost_points); + + ntests++; + result = link_empty1(); + handle_result(result, &lost_points); + + ntests++; + result = link_empty2(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-link", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_lseek.c b/userland/testbin/badcall/bad_lseek.c index a521754..0f3fc23 100644 --- a/userland/testbin/badcall/bad_lseek.c +++ b/userland/testbin/badcall/bad_lseek.c @@ -44,34 +44,38 @@ #include "test.h" static -void +int lseek_fd_device(void) { int fd, rv; + int result; report_begin("lseek on device"); fd = open("null:", O_RDONLY); if (fd<0) { report_warn("opening null: failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } rv = lseek(fd, 309, SEEK_SET); - report_check(rv, errno, ESPIPE); + result = report_check(rv, errno, ESPIPE); close(fd); + + return result; } static -void +int lseek_file_stdin(void) { int fd, fd2, rv, status; const char slogan[] = "There ain't no such thing as a free lunch"; size_t len = strlen(slogan); pid_t pid; + int result; report_begin("lseek stdin when open on file"); @@ -79,27 +83,27 @@ lseek_file_stdin(void) pid = fork(); if (pid<0) { report_warn("fork failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } else if (pid!=0) { /* parent */ rv = waitpid(pid, &status, 0); if (rv<0) { report_warn("waitpid failed"); - report_aborted(); + report_aborted(&result); } if (WIFSIGNALED(status)) { report_warnx("subprocess exited with signal %d", WTERMSIG(status)); - report_aborted(); + report_aborted(&result); } else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { report_warnx("subprocess exited with code %d", WEXITSTATUS(status)); - report_aborted(); + report_aborted(&result); } - return; + return result; } /* child */ @@ -146,133 +150,158 @@ lseek_file_stdin(void) } /* blah */ - report_skipped(); + report_skipped(&result); rv = lseek(STDIN_FILENO, 0, SEEK_SET); report_begin("try 1: SEEK_SET"); - report_check(rv, errno, 0); + result = report_check(rv, errno, 0); rv = lseek(STDIN_FILENO, 0, SEEK_END); report_begin("try 2: SEEK_END"); - report_check(rv, errno, 0); + result = report_check(rv, errno, 0); remove(TESTFILE); _exit(0); } static -void +int lseek_loc_negative(void) { int fd, rv; + int result; report_begin("lseek to negative offset"); fd = open_testfile(NULL); if (fd<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } rv = lseek(fd, -309, SEEK_SET); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); close(fd); remove(TESTFILE); + + return result; } static -void +int lseek_whence_inval(void) { int fd, rv; + int result; report_begin("lseek with invalid whence code"); fd = open_testfile(NULL); if (fd<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } rv = lseek(fd, 0, 3594); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); close(fd); remove(TESTFILE); + return result; } static -void +int lseek_loc_pasteof(void) { const char *message = "blahblah"; int fd; off_t pos; + int result; report_begin("seek past/to EOF"); fd = open_testfile(message); if (fd<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } pos = lseek(fd, 5340, SEEK_SET); if (pos == -1) { report_warn("lseek past EOF failed"); - report_failure(); + report_failure(&result); goto out; } if (pos != 5340) { report_warnx("lseek to 5340 got offset %lld", (long long) pos); - report_failure(); + report_failure(&result); goto out; } pos = lseek(fd, -50, SEEK_CUR); if (pos == -1) { report_warn("small seek beyond EOF failed"); - report_failure(); + report_failure(&result); goto out; } if (pos != 5290) { report_warnx("SEEK_CUR to 5290 got offset %lld", (long long) pos); - report_failure(); + report_failure(&result); goto out; } pos = lseek(fd, 0, SEEK_END); if (pos == -1) { report_warn("seek to EOF failed"); - report_failure(); + report_failure(&result); goto out; } if (pos != (off_t) strlen(message)) { report_warnx("seek to EOF got %lld (should be %zu)", (long long) pos, strlen(message)); - report_failure(); + report_failure(&result); goto out; } - report_passed(); + report_passed(&result); out: close(fd); remove(TESTFILE); - return; + return result; } void test_lseek(void) { - test_lseek_fd(); + int ntests = 0, lost_points = 0; + int result; - lseek_fd_device(); - lseek_file_stdin(); - lseek_loc_negative(); - lseek_loc_pasteof(); - lseek_whence_inval(); + test_lseek_fd(&ntests, &lost_points); + + ntests++; + result = lseek_fd_device(); + handle_result(result, &lost_points); + + ntests++; + result = lseek_file_stdin(); + handle_result(result, &lost_points); + + ntests++; + result = lseek_loc_negative(); + handle_result(result, &lost_points); + + ntests++; + result = lseek_loc_pasteof(); + handle_result(result, &lost_points); + + ntests++; + result = lseek_whence_inval(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-lseek", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_mkdir.c b/userland/testbin/badcall/bad_mkdir.c index 4500dbd..7ab7edd 100644 --- a/userland/testbin/badcall/bad_mkdir.c +++ b/userland/testbin/badcall/bad_mkdir.c @@ -44,44 +44,57 @@ #include "test.h" static -void +int mkdir_dot(void) { int rv; report_begin("mkdir ."); rv = mkdir(".", 0775); - report_check(rv, errno, EEXIST); + return report_check(rv, errno, EEXIST); } static -void +int mkdir_dotdot(void) { int rv; report_begin("mkdir .."); rv = mkdir("..", 0775); - report_check(rv, errno, EEXIST); + return report_check(rv, errno, EEXIST); } static -void +int mkdir_empty(void) { int rv; report_begin("mkdir of empty string"); rv = mkdir("", 0775); - report_check(rv, errno, EINVAL); + return report_check(rv, errno, EINVAL); } void test_mkdir(void) { - test_mkdir_path(); + int ntests = 0, lost_points = 0; + int result; - mkdir_dot(); + test_mkdir_path(&ntests, &lost_points); + + ntests++; + result = mkdir_dot(); + handle_result(result, &lost_points); + + ntests++; mkdir_dotdot(); + handle_result(result, &lost_points); + + ntests++; mkdir_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-mkdir", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_open.c b/userland/testbin/badcall/bad_open.c index 5ce66cd..194725c 100644 --- a/userland/testbin/badcall/bad_open.c +++ b/userland/testbin/badcall/bad_open.c @@ -44,35 +44,47 @@ #include "test.h" static -void +int open_badflags(void) { int fd; report_begin("open null: with bad flags"); fd = open("null:", 309842); - report_check(fd, errno, EINVAL); + return report_check(fd, errno, EINVAL); } static -void +int open_empty(void) { int rv; + int result; report_begin("open empty string"); rv = open("", O_RDONLY); - report_check2(rv, errno, 0, EINVAL); + result = report_check2(rv, errno, 0, EINVAL); if (rv>=0) { close(rv); } + return result; } void test_open(void) { - test_open_path(); + int ntests = 0, lost_points = 0; + int result; - open_badflags(); - open_empty(); + test_open_path(&ntests, &lost_points); + + ntests++; + result = open_badflags(); + handle_result(result, &lost_points); + + ntests++; + result = open_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-open", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_pipe.c b/userland/testbin/badcall/bad_pipe.c index 350c3d8..c581302 100644 --- a/userland/testbin/badcall/bad_pipe.c +++ b/userland/testbin/badcall/bad_pipe.c @@ -44,22 +44,23 @@ #include "test.h" static -void +int pipe_badptr(void *ptr, const char *desc) { int rv; report_begin("%s", desc); rv = pipe(ptr); - report_check(rv, errno, EFAULT); + return report_check(rv, errno, EFAULT); } static -void +int pipe_unaligned(void) { int fds[3], rv; char *ptr; + int result; report_begin("pipe with unaligned pointer"); @@ -67,15 +68,31 @@ pipe_unaligned(void) ptr++; rv = pipe((int *)ptr); - report_survival(rv, errno); + report_survival(rv, errno, &result); + return result; } void test_pipe(void) { - pipe_badptr(NULL, "pipe with NULL pointer"); - pipe_badptr(INVAL_PTR, "pipe with invalid pointer"); - pipe_badptr(KERN_PTR, "pipe with kernel pointer"); + int ntests = 0, lost_points = 0; + int result; - pipe_unaligned(); + ntests++; + result = pipe_badptr(NULL, "pipe with NULL pointer"); + handle_result(result, &lost_points); + + ntests++; + result = pipe_badptr(INVAL_PTR, "pipe with invalid pointer"); + handle_result(result, &lost_points); + + ntests++; + result = pipe_badptr(KERN_PTR, "pipe with kernel pointer"); + handle_result(result, &lost_points); + + ntests++; + result = pipe_unaligned(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-pipe", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_read.c b/userland/testbin/badcall/bad_read.c index c4e3215..d0c529a 100644 --- a/userland/testbin/badcall/bad_read.c +++ b/userland/testbin/badcall/bad_read.c @@ -36,7 +36,12 @@ void test_read(void) { - test_read_fd(); - test_read_buf(); + int ntests = 0, lost_points = 0; + + test_read_fd(&ntests, &lost_points); + test_read_buf(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-read", ntests - lost_points, ntests); + } diff --git a/userland/testbin/badcall/bad_readlink.c b/userland/testbin/badcall/bad_readlink.c index 4399851..53ff792 100644 --- a/userland/testbin/badcall/bad_readlink.c +++ b/userland/testbin/badcall/bad_readlink.c @@ -37,26 +37,28 @@ #include "test.h" static -void +int readlink_file(void) { char buf[128]; int fd, rv; + int result; report_begin("readlink on file"); fd = open_testfile("the question contains an invalid assumption"); if (fd<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } close(fd); rv = readlink(TESTFILE, buf, sizeof(buf)); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); remove(TESTFILE); + return result; } static -void +int readlink_dir(void) { char buf[128]; @@ -64,11 +66,11 @@ readlink_dir(void) report_begin("readlink on ."); rv = readlink(".", buf, sizeof(buf)); - report_check(rv, errno, EISDIR); + return report_check(rv, errno, EISDIR); } static -void +int readlink_empty(void) { char buf[128]; @@ -76,17 +78,30 @@ readlink_empty(void) report_begin("readlink on empty string"); rv = readlink("", buf, sizeof(buf)); - report_check2(rv, errno, EISDIR, EINVAL); + return report_check2(rv, errno, EISDIR, EINVAL); } void test_readlink(void) { - test_readlink_path(); - test_readlink_buf(); + int ntests = 0, lost_points = 0; + int result; - readlink_file(); - readlink_dir(); - readlink_empty(); + test_readlink_path(&ntests, &lost_points); + test_readlink_buf(&ntests, &lost_points); + + ntests++; + result = readlink_file(); + handle_result(result, &lost_points); + + ntests++; + result = readlink_dir(); + handle_result(result, &lost_points); + + ntests++; + result = readlink_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-readlink", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_reboot.c b/userland/testbin/badcall/bad_reboot.c index 8e07f47..68e7c1b 100644 --- a/userland/testbin/badcall/bad_reboot.c +++ b/userland/testbin/badcall/bad_reboot.c @@ -44,7 +44,7 @@ #include "test.h" static -void +int reboot_badflags(void) { int rv; @@ -52,11 +52,18 @@ reboot_badflags(void) tprintf("(This should not kill the system...)\n"); report_begin("reboot with invalid flags"); rv = reboot(15353); - report_check(rv, errno, EINVAL); + return report_check(rv, errno, EINVAL); } void test_reboot(void) { - reboot_badflags(); + int ntests = 0, lost_points = 0; + int result; + + ntests++; + result = reboot_badflags(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-reboot", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_remove.c b/userland/testbin/badcall/bad_remove.c index 02621ac..002866c 100644 --- a/userland/testbin/badcall/bad_remove.c +++ b/userland/testbin/badcall/bad_remove.c @@ -44,63 +44,82 @@ #include "test.h" static -void +int remove_dir(void) { int rv; + int result = FAILED; report_begin("remove() on a directory"); if (create_testdir() < 0) { /*report_aborted();*/ /* XXX in create_testdir */ - return; + return result; } rv = remove(TESTDIR); - report_check(rv, errno, EISDIR); + result = report_check(rv, errno, EISDIR); rmdir(TESTDIR); + + return result; } static -void +int remove_dot(void) { int rv; report_begin("remove() on ."); rv = remove("."); - report_check2(rv, errno, EISDIR, EINVAL); + return report_check2(rv, errno, EISDIR, EINVAL); } static -void +int remove_dotdot(void) { int rv; report_begin("remove() on .."); rv = remove(".."); - report_check2(rv, errno, EISDIR, EINVAL); + return report_check2(rv, errno, EISDIR, EINVAL); } static -void +int remove_empty(void) { int rv; report_begin("remove() on empty string"); rv = remove(""); - report_check2(rv, errno, EISDIR, EINVAL); + return report_check2(rv, errno, EISDIR, EINVAL); } void test_remove(void) { - test_remove_path(); + int ntests = 0, lost_points = 0; + int result; - remove_dir(); - remove_dot(); - remove_dotdot(); - remove_empty(); + test_remove_path(&ntests, &lost_points); + + ntests++; + result = remove_dir(); + handle_result(result, &lost_points); + + ntests++; + result = remove_dot(); + handle_result(result, &lost_points); + + ntests++; + result = remove_dotdot(); + handle_result(result, &lost_points); + + ntests++; + result = remove_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-remove", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_rename.c b/userland/testbin/badcall/bad_rename.c index 814dcb6..ebdba0f 100644 --- a/userland/testbin/badcall/bad_rename.c +++ b/userland/testbin/badcall/bad_rename.c @@ -37,75 +37,99 @@ #include "test.h" static -void +int rename_dot(void) { int rv; + int result; report_begin("rename ."); rv = rename(".", TESTDIR); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); if (rv==0) { /* oops... put it back */ rename(TESTDIR, "."); } + return result; } static -void +int rename_dotdot(void) { int rv; + int result; report_begin("rename .."); rv = rename("..", TESTDIR); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); if (rv==0) { /* oops... put it back */ rename(TESTDIR, ".."); } + return result; } static -void +int rename_empty1(void) { int rv; + int result; report_begin("rename empty string"); rv = rename("", TESTDIR); - report_check2(rv, errno, EISDIR, EINVAL); + result = report_check2(rv, errno, EISDIR, EINVAL); if (rv==0) { /* don't try to remove it */ rename(TESTDIR, TESTDIR "-foo"); } + return result; } static -void +int rename_empty2(void) { int rv; + int result = FAILED; report_begin("rename to empty string"); if (create_testdir()<0) { /*report_aborted();*/ /* XXX in create_testdir */ - return; + return result; } rv = rename(TESTDIR, ""); - report_check2(rv, errno, EISDIR, EINVAL); + result = report_check2(rv, errno, EISDIR, EINVAL); rmdir(TESTDIR); + return result; } void test_rename(void) { - test_rename_paths(); + int ntests = 0, lost_points = 0; + int result; - rename_dot(); - rename_dotdot(); - rename_empty1(); - rename_empty2(); + test_rename_paths(&ntests, &lost_points); + + ntests++; + result = rename_dot(); + handle_result(result, &lost_points); + + ntests++; + result = rename_dotdot(); + handle_result(result, &lost_points); + + ntests++; + result = rename_empty1(); + handle_result(result, &lost_points); + + ntests++; + result = rename_empty2(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-rename", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_rmdir.c b/userland/testbin/badcall/bad_rmdir.c index b1f6883..a72c685 100644 --- a/userland/testbin/badcall/bad_rmdir.c +++ b/userland/testbin/badcall/bad_rmdir.c @@ -44,61 +44,82 @@ #include "test.h" static -void +int rmdir_file(void) { int rv; + int result; report_begin("rmdir a file"); if (create_testfile()<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } rv = rmdir(TESTFILE); - report_check(rv, errno, ENOTDIR); + result = report_check(rv, errno, ENOTDIR); remove(TESTFILE); + + return result; } static -void +int rmdir_dot(void) { int rv; + int result; report_begin("rmdir ."); rv = rmdir("."); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); + return result; } static -void +int rmdir_dotdot(void) { int rv; report_begin("rmdir .."); rv = rmdir(".."); - report_check2(rv, errno, EINVAL, ENOTEMPTY); + return report_check2(rv, errno, EINVAL, ENOTEMPTY); } static -void +int rmdir_empty(void) { int rv; report_begin("rmdir empty string"); rv = rmdir(""); - report_check(rv, errno, EINVAL); + return report_check(rv, errno, EINVAL); } void test_rmdir(void) { - test_rmdir_path(); + int ntests = 0, lost_points = 0; + int result; - rmdir_file(); - rmdir_dot(); - rmdir_dotdot(); - rmdir_empty(); + test_rmdir_path(&ntests, &lost_points); + + ntests++; + result = rmdir_file(); + handle_result(result, &lost_points); + + ntests++; + result = rmdir_dot(); + handle_result(result, &lost_points); + + ntests++; + result = rmdir_dotdot(); + handle_result(result, &lost_points); + + ntests++; + result = rmdir_empty(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-rmdir", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_sbrk.c b/userland/testbin/badcall/bad_sbrk.c index b482a92..59aa314 100644 --- a/userland/testbin/badcall/bad_sbrk.c +++ b/userland/testbin/badcall/bad_sbrk.c @@ -59,7 +59,7 @@ try_sbrk(long val) } static -void +int enforce_sbrk(long val, const char *desc, int err) { int result; @@ -67,59 +67,78 @@ enforce_sbrk(long val, const char *desc, int err) report_begin("sbrk %s", desc); result = try_sbrk(val); - report_check(result, errno, err); + return report_check(result, errno, err); } static -void +int sbrk_bigpos(void) { - enforce_sbrk(4096*1024*256, "huge positive", ENOMEM); + return enforce_sbrk(4096*1024*256, "huge positive", ENOMEM); } static -void +int sbrk_bigneg(void) { - enforce_sbrk(-4096*1024*256, "huge negative", EINVAL); + return enforce_sbrk(-4096*1024*256, "huge negative", EINVAL); } static -void +int sbrk_neg(void) { - enforce_sbrk(-8192, "too-large negative", EINVAL); + return enforce_sbrk(-8192, "too-large negative", EINVAL); } static -void +int sbrk_unalignedpos(void) { int result; report_begin("sbrk unaligned positive"); result = try_sbrk(17); - report_check2(result, errno, 0, EINVAL); + return report_check2(result, errno, 0, EINVAL); } static -void +int sbrk_unalignedneg(void) { int result; report_begin("sbrk unaligned negative"); result = try_sbrk(-17); - report_check2(result, errno, 0, EINVAL); + return report_check2(result, errno, 0, EINVAL); } void test_sbrk(void) { - sbrk_neg(); - sbrk_bigpos(); - sbrk_bigneg(); - sbrk_unalignedpos(); - sbrk_unalignedneg(); + int ntests = 0, lost_points = 0; + int result; + + ntests++; + result = sbrk_neg(); + handle_result(result, &lost_points); + + ntests++; + result = sbrk_bigpos(); + handle_result(result, &lost_points); + + ntests++; + result = sbrk_bigneg(); + handle_result(result, &lost_points); + + ntests++; + result = sbrk_unalignedpos(); + handle_result(result, &lost_points); + + ntests++; + result = sbrk_unalignedneg(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-sbrk", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_stat.c b/userland/testbin/badcall/bad_stat.c index 726f9b1..71c00c8 100644 --- a/userland/testbin/badcall/bad_stat.c +++ b/userland/testbin/badcall/bad_stat.c @@ -67,7 +67,7 @@ badbuf_stat(struct stat *sb) } static -void +int common_badbuf(int (*statfunc)(struct stat *), void *ptr, const char *call, const char *ptrdesc) { @@ -75,22 +75,24 @@ common_badbuf(int (*statfunc)(struct stat *), void *ptr, report_begin("%s with %s buf", call, ptrdesc); rv = statfunc(ptr); - report_check(rv, errno, EFAULT); + return report_check(rv, errno, EFAULT); } static -void +int any_badbuf(int (*statfunc)(struct stat *), const char *call) { - common_badbuf(statfunc, NULL, call, "NULL"); - common_badbuf(statfunc, INVAL_PTR, call, "invalid pointer"); - common_badbuf(statfunc, KERN_PTR, call, "kernel pointer"); + int result; + result = common_badbuf(statfunc, NULL, call, "NULL"); + result |= common_badbuf(statfunc, INVAL_PTR, call, "invalid pointer"); + result |= common_badbuf(statfunc, KERN_PTR, call, "kernel pointer"); + return result; } //////////////////////////////////////////////////////////// static -void +int any_empty(int (*statfunc)(const char *, struct stat *), const char *call) { struct stat sb; @@ -98,7 +100,7 @@ any_empty(int (*statfunc)(const char *, struct stat *), const char *call) report_begin("%s on empty string", call); rv = statfunc("", &sb); - report_check2(rv, errno, 0, EINVAL); + return report_check2(rv, errno, 0, EINVAL); } //////////////////////////////////////////////////////////// @@ -106,23 +108,53 @@ any_empty(int (*statfunc)(const char *, struct stat *), const char *call) void test_fstat(void) { - test_fstat_fd(); - any_badbuf(badbuf_fstat, "fstat"); + int ntests = 0, lost_points = 0; + int result; + + test_fstat_fd(&ntests, &lost_points); + + ntests++; + result = any_badbuf(badbuf_fstat, "fstat"); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-fstat", ntests - lost_points, ntests); } void test_lstat(void) { - test_lstat_path(); - any_empty(lstat, "lstat"); - any_badbuf(badbuf_lstat, "lstat"); + int ntests = 0, lost_points = 0; + int result; + + test_lstat_path(&ntests, &lost_points); + + ntests++; + result = any_empty(lstat, "lstat"); + handle_result(result, &lost_points); + + ntests++; + result = any_badbuf(badbuf_lstat, "lstat"); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-lstat", ntests - lost_points, ntests); } void test_stat(void) { - test_stat_path(); - any_empty(stat, "stat"); - any_badbuf(badbuf_stat, "stat"); + int ntests = 0, lost_points = 0; + int result; + + test_stat_path(&ntests, &lost_points); + + ntests++; + result = any_empty(stat, "stat"); + handle_result(result, &lost_points); + + ntests++; + result = any_badbuf(badbuf_stat, "stat"); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-stat", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_symlink.c b/userland/testbin/badcall/bad_symlink.c index 68a3463..9d12507 100644 --- a/userland/testbin/badcall/bad_symlink.c +++ b/userland/testbin/badcall/bad_symlink.c @@ -37,32 +37,46 @@ #include "test.h" static -void +int symlink_empty1(void) { int rv; + int result; report_begin("symlink -> empty string"); rv = symlink("", TESTLINK); - report_check2(rv, errno, 0, EINVAL); + result = report_check2(rv, errno, 0, EINVAL); remove(TESTLINK); + return result; } static -void +int symlink_empty2(void) { int rv; report_begin("symlink named empty string"); rv = symlink("foo", ""); - report_check(rv, errno, EINVAL); + return report_check(rv, errno, EINVAL); } void test_symlink(void) { - test_symlink_paths(); - symlink_empty1(); - symlink_empty2(); + int ntests = 0, lost_points = 0; + int result; + + + test_symlink_paths(&ntests, &lost_points); + + ntests++; + result = symlink_empty1(); + handle_result(result, &lost_points); + + ntests++; + result = symlink_empty2(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-symlink", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_time.c b/userland/testbin/badcall/bad_time.c index c5df61c..7303c12 100644 --- a/userland/testbin/badcall/bad_time.c +++ b/userland/testbin/badcall/bad_time.c @@ -44,33 +44,48 @@ #include "test.h" static -void +int time_badsecs(void *ptr, const char *desc) { int rv; report_begin("%s", desc); rv = __time(ptr, NULL); - report_check(rv, errno, EFAULT); + return report_check(rv, errno, EFAULT); } static -void +int time_badnsecs(void *ptr, const char *desc) { int rv; report_begin("%s", desc); rv = __time(NULL, ptr); - report_check(rv, errno, EFAULT); + return report_check(rv, errno, EFAULT); } void test_time(void) { - time_badsecs(INVAL_PTR, "__time with invalid seconds pointer"); - time_badsecs(KERN_PTR, "__time with kernel seconds pointer"); + int ntests = 0, lost_points = 0; + int result; - time_badnsecs(INVAL_PTR, "__time with invalid nsecs pointer"); - time_badnsecs(KERN_PTR, "__time with kernel nsecs pointer"); + ntests++; + result = time_badsecs(INVAL_PTR, "__time with invalid seconds pointer"); + handle_result(result, &lost_points); + + ntests++; + result = time_badsecs(KERN_PTR, "__time with kernel seconds pointer"); + handle_result(result, &lost_points); + + ntests++; + result = time_badnsecs(INVAL_PTR, "__time with invalid nsecs pointer"); + handle_result(result, &lost_points); + + ntests++; + result = time_badnsecs(KERN_PTR, "__time with kernel nsecs pointer"); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-time", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_waitpid.c b/userland/testbin/badcall/bad_waitpid.c index f9bbd0d..55d6c04 100644 --- a/userland/testbin/badcall/bad_waitpid.c +++ b/userland/testbin/badcall/bad_waitpid.c @@ -42,7 +42,7 @@ #include "test.h" static -void +int wait_badpid(pid_t pid, const char *desc) { pid_t rv; @@ -59,23 +59,24 @@ wait_badpid(pid_t pid, const char *desc) else if (err == ENOSYS) { report_saw_enosys(); } - report_check2(rv, err, ESRCH, ECHILD); + return report_check2(rv, err, ESRCH, ECHILD); } static -void +int wait_nullstatus(void) { pid_t pid, rv; int x; + int result; report_begin("wait with NULL status"); pid = fork(); if (pid<0) { report_warn("fork failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } if (pid==0) { exit(0); @@ -83,50 +84,54 @@ wait_nullstatus(void) /* POSIX explicitly says passing NULL for status is allowed */ rv = waitpid(pid, NULL, 0); - report_check(rv, errno, 0); + result = report_check(rv, errno, 0); waitpid(pid, &x, 0); + return result; } static -void +int wait_badstatus(void *ptr, const char *desc) { pid_t pid, rv; int x; + int result; report_begin(desc); pid = fork(); if (pid<0) { report_warn("fork failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } if (pid==0) { exit(0); } rv = waitpid(pid, ptr, 0); - report_check(rv, errno, EFAULT); + result = report_check(rv, errno, EFAULT); waitpid(pid, &x, 0); + return result; } static -void +int wait_unaligned(void) { pid_t pid, rv; int x; int status[2]; /* will have integer alignment */ char *ptr; + int result; report_begin("wait with unaligned status"); pid = fork(); if (pid<0) { report_warn("fork failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } if (pid==0) { exit(0); @@ -139,55 +144,61 @@ wait_unaligned(void) ptr++; rv = waitpid(pid, (int *)ptr, 0); - report_survival(rv, errno); + report_survival(rv, errno, &result); if (rv<0) { waitpid(pid, &x, 0); } + return result; } static -void +int wait_badflags(void) { pid_t pid, rv; int x; + int result; report_begin("wait with bad flags"); pid = fork(); if (pid<0) { report_warn("fork failed"); - report_aborted(); - return; + report_aborted(&result); + return result; } if (pid==0) { exit(0); } rv = waitpid(pid, &x, 309429); - report_check(rv, errno, EINVAL); + result = report_check(rv, errno, EINVAL); waitpid(pid, &x, 0); + return result; } static -void +int wait_self(void) { pid_t rv; int x; + int result; report_begin("wait for self"); rv = waitpid(getpid(), &x, 0); - report_survival(rv, errno); + report_survival(rv, errno, &result); + return result; } static -void +int wait_parent(void) { pid_t mypid, childpid, rv; int x; + int result; report_begin("wait for parent"); report_hassubs(); @@ -196,30 +207,32 @@ wait_parent(void) childpid = fork(); if (childpid<0) { report_warn("can't fork"); - report_aborted(); - return; + report_aborted(&result); + return result; } if (childpid==0) { /* Child. Wait for parent. */ rv = waitpid(mypid, &x, 0); report_beginsub("from child:"); - report_survival(rv, errno); + report_survival(rv, errno, &result); _exit(0); } rv = waitpid(childpid, &x, 0); report_beginsub("from parent:"); - report_survival(rv, errno); + report_survival(rv, errno, &result); + return result; } //////////////////////////////////////////////////////////// static -void +int wait_siblings_child(const char *semname) { pid_t pids[2], mypid, otherpid; int rv, fd, semfd, x; char c; + int result; mypid = getpid(); @@ -244,7 +257,7 @@ wait_siblings_child(const char *semname) if (fd<0) { report_warn("child process (pid %d) can't open %s", mypid, TESTFILE); - return; + return FAILED; } /* @@ -257,13 +270,13 @@ wait_siblings_child(const char *semname) if (rv<0) { report_warn("child process (pid %d) lseek error", mypid); - return; + return FAILED; } rv = read(fd, pids, sizeof(pids)); if (rv<0) { report_warn("child process (pid %d) read error", mypid); - return; + return FAILED; } } while (rv < (int)sizeof(pids)); @@ -276,23 +289,25 @@ wait_siblings_child(const char *semname) else { report_warn("child process (pid %d) got garbage in comm file", mypid); - return; + return FAILED; } close(fd); rv = waitpid(otherpid, &x, 0); report_beginsub("sibling (pid %d)", mypid); - report_survival(rv, errno); + report_survival(rv, errno, &result); + return result; } static -void +int wait_siblings(void) { pid_t pids[2]; int rv, fd, semfd, x; int bad = 0; char semname[32]; + int result; /* This test may also blow up if FS synchronization is substandard */ @@ -303,26 +318,26 @@ wait_siblings(void) semfd = open(semname, O_WRONLY|O_CREAT|O_TRUNC, 0664); if (semfd < 0) { report_warn("can't make semaphore"); - report_aborted(); - return; + report_aborted(&result); + return result; } fd = open_testfile(NULL); if (fd<0) { - report_aborted(); + report_aborted(&result); close(semfd); remove(semname); - return; + return result; } pids[0] = fork(); if (pids[0]<0) { report_warn("can't fork"); - report_aborted(); + report_aborted(&result); close(fd); close(semfd); remove(semname); - return; + return result; } if (pids[0]==0) { close(fd); @@ -334,12 +349,12 @@ wait_siblings(void) pids[1] = fork(); if (pids[1]<0) { report_warn("can't fork"); - report_aborted(); + report_aborted(&result); /* abandon the other child process :( */ close(fd); close(semfd); remove(semname); - return; + return result; } if (pids[1]==0) { close(fd); @@ -351,21 +366,21 @@ wait_siblings(void) rv = write(fd, pids, sizeof(pids)); if (rv < 0) { report_warn("write error on %s", TESTFILE); - report_aborted(); + report_aborted(&result); /* abandon child procs :( */ close(fd); close(semfd); remove(semname); - return; + return result; } if (rv != (int)sizeof(pids)) { report_warnx("write error on %s: short count", TESTFILE); - report_aborted(); + report_aborted(&result); /* abandon child procs :( */ close(fd); close(semfd); remove(semname); - return; + return result; } /* gate the child procs */ @@ -388,15 +403,17 @@ wait_siblings(void) } if (bad) { /* XXX: aborted, or failure, or what? */ - report_aborted(); + report_aborted(&result); } else { - report_passed(); + report_passed(&result); } close(fd); close(semfd); remove(semname); remove(TESTFILE); + + return result; } //////////////////////////////////////////////////////////// @@ -404,20 +421,60 @@ wait_siblings(void) void test_waitpid(void) { - wait_badpid(-8, "wait for pid -8"); - wait_badpid(-1, "wait for pid -1"); - wait_badpid(0, "pid zero"); - wait_badpid(NONEXIST_PID, "nonexistent pid"); + int ntests = 0, lost_points = 0; + int result; - wait_nullstatus(); - wait_badstatus(INVAL_PTR, "wait with invalid pointer status"); - wait_badstatus(KERN_PTR, "wait with kernel pointer status"); + ntests++; + result = wait_badpid(-8, "wait for pid -8"); + handle_result(result, &lost_points); - wait_unaligned(); + ntests++; + result = wait_badpid(-1, "wait for pid -1"); + handle_result(result, &lost_points); - wait_badflags(); + ntests++; + result = wait_badpid(0, "pid zero"); + handle_result(result, &lost_points); - wait_self(); - wait_parent(); - wait_siblings(); + ntests++; + result = wait_badpid(NONEXIST_PID, "nonexistent pid"); + handle_result(result, &lost_points); + + + ntests++; + result = wait_nullstatus(); + handle_result(result, &lost_points); + + ntests++; + result = wait_badstatus(INVAL_PTR, "wait with invalid pointer status"); + handle_result(result, &lost_points); + + ntests++; + result = wait_badstatus(KERN_PTR, "wait with kernel pointer status"); + handle_result(result, &lost_points); + + + ntests++; + result = wait_unaligned(); + handle_result(result, &lost_points); + + + ntests++; + result = wait_badflags(); + handle_result(result, &lost_points); + + + ntests++; + result = wait_self(); + handle_result(result, &lost_points); + + ntests++; + result = wait_parent(); + handle_result(result, &lost_points); + + ntests++; + result = wait_siblings(); + handle_result(result, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-waitpid", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/bad_write.c b/userland/testbin/badcall/bad_write.c index 8a79803..6e9d100 100644 --- a/userland/testbin/badcall/bad_write.c +++ b/userland/testbin/badcall/bad_write.c @@ -36,6 +36,10 @@ void test_write(void) { - test_write_fd(); - test_write_buf(); + int ntests = 0, lost_points = 0; + + test_write_fd(&ntests, &lost_points); + test_write_buf(&ntests, &lost_points); + + partial_credit(SECRET, "/testbin/badcall-write", ntests - lost_points, ntests); } diff --git a/userland/testbin/badcall/common_buf.c b/userland/testbin/badcall/common_buf.c index 37f7eaa..cde9496 100644 --- a/userland/testbin/badcall/common_buf.c +++ b/userland/testbin/badcall/common_buf.c @@ -175,33 +175,46 @@ getcwd_badbuf(void *buf) //////////////////////////////////////////////////////////// static -void +int common_badbuf(struct buftest *info, void *buf, const char *bufdesc) { int rv; - + int result; report_begin("%s with %s buffer", info->name, bufdesc); info->setup(); rv = info->op(buf); - report_check(rv, errno, EFAULT); + result = report_check(rv, errno, EFAULT); info->cleanup(); + return result; } static -void -any_badbuf(struct buftest *info) +int +any_badbuf(struct buftest *info, int *ntests, int *lost_points) { - common_badbuf(info, NULL, "NULL"); - common_badbuf(info, INVAL_PTR, "invalid"); - common_badbuf(info, KERN_PTR, "kernel-space"); + int result; + + *ntests += 1; + result = common_badbuf(info, NULL, "NULL"); + handle_result(result, lost_points); + + *ntests += 1; + result = common_badbuf(info, INVAL_PTR, "invalid"); + handle_result(result, lost_points); + + *ntests += 1; + result = common_badbuf(info, KERN_PTR, "kernel-space"); + handle_result(result, lost_points); + + return result; } //////////////////////////////////////////////////////////// #define T(call) \ void \ - test_##call##_buf(void) \ + test_##call##_buf(int *ntests, int *lost_points) \ { \ static struct buftest info = { \ call##_setup, \ @@ -209,7 +222,7 @@ any_badbuf(struct buftest *info) call##_cleanup, \ #call, \ }; \ - any_badbuf(&info); \ + any_badbuf(&info, ntests, lost_points); \ } T(read); diff --git a/userland/testbin/badcall/common_fds.c b/userland/testbin/badcall/common_fds.c index 173db73..032c474 100644 --- a/userland/testbin/badcall/common_fds.c +++ b/userland/testbin/badcall/common_fds.c @@ -138,46 +138,58 @@ dup2_cleanup(void) //////////////////////////////////////////////////////////// static -void +int any_badfd(int (*func)(int fd), void (*cleanup)(void), const char *callname, int fd, const char *fddesc) { int rv; - + int result; report_begin("%s using %s", callname, fddesc); rv = func(fd); - report_check(rv, errno, EBADF); + result = report_check(rv, errno, EBADF); if (cleanup) { cleanup(); } + return result; } static void runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname, - enum rwtestmodes rw) + enum rwtestmodes rw, int *ntests, int *lost_points) { int fd; + int result; /* * If adding cases, also see bad_dup2.c */ /* basic invalid case: fd -1 */ - any_badfd(func, cleanup, callname, -1, "fd -1"); + *ntests += 1; + result = any_badfd(func, cleanup, callname, -1, "fd -1"); + handle_result(result, lost_points); /* also try -5 in case -1 is special somehow */ - any_badfd(func, cleanup, callname, -5, "fd -5"); + *ntests += 1; + result = any_badfd(func, cleanup, callname, -5, "fd -5"); + handle_result(result, lost_points); /* try a fd we know is closed */ - any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd"); + *ntests += 1; + result = any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd"); + handle_result(result, lost_points); /* try a positive fd we know is out of range */ - any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd"); + *ntests += 1; + result = any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd"); + handle_result(result, lost_points); /* test for off-by-one errors */ #ifdef OPEN_MAX - any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX"); + *ntests += 1; + result = any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX"); + handle_result(result, lost_points); #else warnx("Warning: OPEN_MAX not defined, test skipped"); #endif @@ -188,8 +200,10 @@ runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname, /* already printed a message */ } else { - any_badfd(func, cleanup, callname, fd, + *ntests += 1; + result = any_badfd(func, cleanup, callname, fd, "fd opened read-only"); + handle_result(result, lost_points); } close(fd); } @@ -199,8 +213,10 @@ runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname, /* already printed a message */ } else { - any_badfd(func, cleanup, callname, fd, + *ntests += 1; + result = any_badfd(func, cleanup, callname, fd, "fd opened write-only"); + handle_result(result, lost_points); } close(fd); } @@ -208,18 +224,18 @@ runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname, //////////////////////////////////////////////////////////// -#define T(call, rw) \ - void \ - test_##call##_fd(void) \ - { \ - runtest(call##_badfd, NULL, #call, rw); \ +#define T(call, rw) \ + void \ + test_##call##_fd(int *ntests, int *lost_points) \ + { \ + runtest(call##_badfd, NULL, #call, rw, ntests, lost_points); \ } -#define TC(call, rw) \ - void \ - test_##call##_fd(void) \ - { \ - runtest(call##_badfd, call##_cleanup, #call, rw);\ +#define TC(call, rw) \ + void \ + test_##call##_fd(int *ntests, int *lost_points) \ + { \ + runtest(call##_badfd, call##_cleanup, #call, rw, ntests, lost_points); \ } T(read, RW_TEST_WRONLY); diff --git a/userland/testbin/badcall/common_path.c b/userland/testbin/badcall/common_path.c index 1a8ff9d..0a00cb6 100644 --- a/userland/testbin/badcall/common_path.c +++ b/userland/testbin/badcall/common_path.c @@ -148,46 +148,58 @@ stat_badpath(const char *name) //////////////////////////////////////////////////////////// static -void +int common_badpath(int (*func)(const char *path), int mk, int rm, const char *path, const char *call, const char *pathdesc) { int rv; + int result; report_begin("%s with %s path", call, pathdesc); if (mk) { if (create_testfile()<0) { - report_aborted(); - return; + report_aborted(&result); + return result; } } rv = func(path); - report_check(rv, errno, EFAULT); + result = report_check(rv, errno, EFAULT); if (mk || rm) { remove(TESTFILE); } + return result; } static void -any_badpath(int (*func)(const char *path), const char *call, int mk, int rm) +any_badpath(int (*func)(const char *path), const char *call, int mk, int rm, + int *ntests, int *lost_points) { - common_badpath(func, mk, rm, NULL, call, "NULL"); - common_badpath(func, mk, rm, INVAL_PTR, call, "invalid-pointer"); - common_badpath(func, mk, rm, KERN_PTR, call, "kernel-pointer"); + int result; + // We have a total of 3 tests + *ntests = *ntests + 3; + + result = common_badpath(func, mk, rm, NULL, call, "NULL"); + handle_result(result, lost_points); + + result = common_badpath(func, mk, rm, INVAL_PTR, call, "invalid-pointer"); + handle_result(result, lost_points); + + result = common_badpath(func, mk, rm, KERN_PTR, call, "kernel-pointer"); + handle_result(result, lost_points); } //////////////////////////////////////////////////////////// /* functions with one pathname */ -#define T(call) \ - void \ - test_##call##_path(void) \ - { \ - any_badpath(call##_badpath, #call, 0, 0); \ +#define T(call) \ + void \ + test_##call##_path(int *ntests, int *lost_points) \ + { \ + any_badpath(call##_badpath, #call, 0, 0, ntests, lost_points); \ } T(open); @@ -200,12 +212,12 @@ T(stat); T(lstat); /* functions with two pathnames */ -#define T2(call) \ - void \ - test_##call##_paths(void) \ - { \ - any_badpath(call##_badpath1, #call "(arg1)", 0, 1); \ - any_badpath(call##_badpath2, #call "(arg2)", 1, 1); \ +#define T2(call) \ + void \ + test_##call##_paths(int *ntests, int *lost_points) \ + { \ + any_badpath(call##_badpath1, #call "(arg1)", 0, 1, ntests, lost_points); \ + any_badpath(call##_badpath2, #call "(arg2)", 1, 1, ntests, lost_points); \ } T2(rename); diff --git a/userland/testbin/badcall/driver.c b/userland/testbin/badcall/driver.c index 7a0ac41..9155271 100644 --- a/userland/testbin/badcall/driver.c +++ b/userland/testbin/badcall/driver.c @@ -121,16 +121,18 @@ int create_testdir(void) { int rv; + int result; + rv = mkdir(TESTDIR, 0775); if (rv<0) { if (errno == ENOSYS) { report_saw_enosys(); report_warnx("mkdir unimplemented; cannot run test"); - report_skipped(); + report_skipped(&result); } else { report_warn("mkdir %s failed", TESTDIR); - report_aborted(); + report_aborted(&result); } return -1; } diff --git a/userland/testbin/badcall/report.c b/userland/testbin/badcall/report.c index f93c7cf..fc7ca4e 100644 --- a/userland/testbin/badcall/report.c +++ b/userland/testbin/badcall/report.c @@ -251,27 +251,31 @@ report_end(const char *msg) } void -report_passed(void) +report_passed(int *status) { report_end("passed"); + *status = SUCCESS; } void -report_failure(void) +report_failure(int *status) { report_end("FAILURE"); + *status = FAILED; } void -report_skipped(void) +report_skipped(int *status) { report_end("------"); + *status = SKIPPED; } void -report_aborted(void) +report_aborted(int *status) { report_end("ABORTED"); + *status = ABORTED; } //////////////////////////////////////////////////////////// @@ -283,18 +287,19 @@ report_aborted(void) */ void -report_survival(int rv, int error) +report_survival(int rv, int error, int *result) { /* allow any error as long as we survive */ report_result(rv, error); - report_passed(); + report_passed(result); } static -void +int report_checkN(int rv, int error, int *right_errors, int right_num) { int i, goterror; + int result = 1; if (rv==-1) { goterror = error; @@ -306,39 +311,40 @@ report_checkN(int rv, int error, int *right_errors, int right_num) for (i=0; i + #define TESTFILE "badcallfile" #define TESTDIR "badcalldir" #define TESTLINK "badcalllink" @@ -37,6 +39,11 @@ #define PF(a, b) #endif +#define SUCCESS 0 +#define SKIPPED 1 +#define FAILED 2 +#define ABORTED 3 + /* driver.c */ int open_testfile(const char *str); int reopen_testfile(int openflags); @@ -52,46 +59,46 @@ PF(1, 2) void report_warn(const char *fmt, ...); PF(1, 2) void report_warnx(const char *fmt, ...); void report_result(int rv, int error); void report_saw_enosys(void); -void report_passed(void); -void report_failure(void); -void report_skipped(void); -void report_aborted(void); -void report_survival(int rv, int error); -void report_check(int rv, int error, int right_error); -void report_check2(int rv, int error, int okerr1, int okerr2); -void report_check3(int rv, int error, int okerr1, int okerr2, int okerr3); +void report_passed(int *result); +void report_failure(int *result); +void report_skipped(int *result); +void report_aborted(int *result); +void report_survival(int rv, int error, int *result); +int report_check(int rv, int error, int right_error); +int report_check2(int rv, int error, int okerr1, int okerr2); +int report_check3(int rv, int error, int okerr1, int okerr2, int okerr3); /* common_buf.c */ -void test_read_buf(void); -void test_write_buf(void); -void test_getdirentry_buf(void); -void test_getcwd_buf(void); -void test_readlink_buf(void); +void test_read_buf(int *ntests, int *lost_points); +void test_write_buf(int *ntests, int *lost_points); +void test_getdirentry_buf(int *ntests, int *lost_points); +void test_getcwd_buf(int *ntests, int *lost_points); +void test_readlink_buf(int *ntests, int *lost_points); /* common_fds.c */ -void test_read_fd(void); -void test_write_fd(void); -void test_close_fd(void); -void test_ioctl_fd(void); -void test_lseek_fd(void); -void test_fsync_fd(void); -void test_ftruncate_fd(void); -void test_fstat_fd(void); -void test_getdirentry_fd(void); -void test_dup2_fd(void); +void test_read_fd(int *ntests, int *lost_points); +void test_write_fd(int *ntests, int *lost_points); +void test_close_fd(int *ntests, int *lost_points); +void test_ioctl_fd(int *ntests, int *lost_points); +void test_lseek_fd(int *ntests, int *lost_points); +void test_fsync_fd(int *ntests, int *lost_points); +void test_ftruncate_fd(int *ntests, int *lost_points); +void test_fstat_fd(int *ntests, int *lost_points); +void test_getdirentry_fd(int *ntests, int *lost_points); +void test_dup2_fd(int *ntests, int *lost_points); /* common_path.c */ -void test_open_path(void); -void test_remove_path(void); -void test_rename_paths(void); -void test_link_paths(void); -void test_mkdir_path(void); -void test_rmdir_path(void); -void test_chdir_path(void); -void test_symlink_paths(void); -void test_readlink_path(void); -void test_stat_path(void); -void test_lstat_path(void); +void test_open_path(int *ntests, int *lost_points); +void test_remove_path(int *ntests, int *lost_points); +void test_rename_paths(int *ntests, int *lost_points); +void test_link_paths(int *ntests, int *lost_points); +void test_mkdir_path(int *ntests, int *lost_points); +void test_rmdir_path(int *ntests, int *lost_points); +void test_chdir_path(int *ntests, int *lost_points); +void test_symlink_paths(int *ntests, int *lost_points); +void test_readlink_path(int *ntests, int *lost_points); +void test_stat_path(int *ntests, int *lost_points); +void test_lstat_path(int *ntests, int *lost_points); /* bad_*.c */ void test_execv(void); @@ -122,3 +129,6 @@ void test_time(void); void test_getcwd(void); void test_stat(void); void test_lstat(void); /* in bad_stat.c */ + +void handle_result(int result, int *lost_points); + diff --git a/userland/testbin/bigexec/bigexec.c b/userland/testbin/bigexec/bigexec.c index c417d81..994c969 100644 --- a/userland/testbin/bigexec/bigexec.c +++ b/userland/testbin/bigexec/bigexec.c @@ -41,6 +41,7 @@ #include #include #include +#include #define _PATH_MYSELF "/testbin/bigexec" @@ -377,6 +378,7 @@ main(int argc, char *argv[]) else if (checkmany(argc, argv, 1000, word8)) { #endif warnx("Complete."); + success(TEST161_SUCCESS, SECRET, "/testbin/bigexec"); return 0; } else { @@ -384,4 +386,5 @@ main(int argc, char *argv[]) dumpargs(argc, argv); return 1; } + success(TEST161_SUCCESS, SECRET, "/testbin/bigexec"); } diff --git a/userland/testbin/closetest/Makefile b/userland/testbin/closetest/Makefile new file mode 100644 index 0000000..cf9b514 --- /dev/null +++ b/userland/testbin/closetest/Makefile @@ -0,0 +1,11 @@ +# Makefile for closetest + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=closetest +SRCS=closetest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/closetest/closetest.c b/userland/testbin/closetest/closetest.c new file mode 100644 index 0000000..5f23a71 --- /dev/null +++ b/userland/testbin/closetest/closetest.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * closetest.c + * + * Tests the close syscall + * + * This should run correctly when open and close are implemented correctly. + */ + +#include +#include +#include +#include +#include +#include + + +int +main(int argc, char **argv) +{ + + // Assume argument passing is *not* supported. + + (void) argc; + (void) argv; + + int ret, fd = -1; + // Try to open a file and then close it + fd = open("sys161.conf", O_RDONLY); + if(fd < 0) { + err(-1, "Open syscall failed"); + } + else if(fd < 3) { + warnx("Open syscall returned number(%d) used by standard file descriptors (0,1,2)", fd); + } + + ret = close(fd); + if(ret) { + err(1, "Failed to close file\n"); + } + + // Can we close 0? + ret = close(0); + if(ret) { + err(1, "Failed to close STDIN\n"); + } + + + success(TEST161_SUCCESS, SECRET, "/testbin/closetest"); + // Exit may not be implemented. So crash. + crash_prog(); + return 0; +} diff --git a/userland/testbin/consoletest/Makefile b/userland/testbin/consoletest/Makefile new file mode 100644 index 0000000..d3a1d8c --- /dev/null +++ b/userland/testbin/consoletest/Makefile @@ -0,0 +1,11 @@ +# Makefile for consoletest + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=consoletest +SRCS=consoletest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/consoletest/consoletest.c b/userland/testbin/consoletest/consoletest.c new file mode 100644 index 0000000..650c2d4 --- /dev/null +++ b/userland/testbin/consoletest/consoletest.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * consoletest.c + * + * Tests whether console can be written to. + * + * This should run correctly when open and write syscalls are correctly implemented + */ + +#include +#include +#include +#include +#include +#include + +// 23 Mar 2012 : GWA : BUFFER_COUNT must be even. + +int +main(int argc, char **argv) +{ + + // 23 Mar 2012 : GWA : Assume argument passing is *not* supported. + + (void) argc; + (void) argv; + + secprintf(SECRET, "Able was i ere i saw elbA\n", "/testbin/consoletest"); + + // Guru: Since exit() may not yet be implemented, just trigger a + // failure that the grading scripts expect to see. + tprintf("Accessing invalid memory location to trigger failure\n"); + tprintf("%d", *((int *) 0xd34db33f)); + + return 0; +} diff --git a/userland/testbin/crash/crash.c b/userland/testbin/crash/crash.c index 10c2541..50d61de 100644 --- a/userland/testbin/crash/crash.c +++ b/userland/testbin/crash/crash.c @@ -46,6 +46,8 @@ #include #include #include +#include + #if defined(__mips__) #define KERNEL_ADDR 0x80000000 @@ -384,5 +386,7 @@ main(int argc, char **argv) } } } + printf("Should print success\n"); + success(TEST161_SUCCESS, SECRET, "/testbin/crash"); return 0; } diff --git a/userland/testbin/factorial/factorial.c b/userland/testbin/factorial/factorial.c index ef95e49..1757647 100644 --- a/userland/testbin/factorial/factorial.c +++ b/userland/testbin/factorial/factorial.c @@ -32,6 +32,7 @@ #include #include #include +#include #define _PATH_SELF "/testbin/factorial" @@ -246,6 +247,7 @@ main(int argc, char *argv[]) else if (argc == 3) { if (!strcmp(argv[1], "1") || !strcmp(argv[1], "0")) { tprintf("%s\n", argv[2]); + secprintf(SECRET, argv[2], "/testbin/factorial"); } else { number_init(&n1, argv[1]); diff --git a/userland/testbin/fileonlytest/fileonlytest.c b/userland/testbin/fileonlytest/fileonlytest.c index 44ea585..bdf73cb 100644 --- a/userland/testbin/fileonlytest/fileonlytest.c +++ b/userland/testbin/fileonlytest/fileonlytest.c @@ -41,6 +41,9 @@ #include #include #include +#include + +#include // 23 Mar 2012 : GWA : BUFFER_COUNT must be even. @@ -55,7 +58,7 @@ main(int argc, char **argv) { // 23 Mar 2012 : GWA : Assume argument passing is *not* supported. - + (void) argc; (void) argv; int i, j; @@ -72,12 +75,12 @@ main(int argc, char **argv) if (fh < 0) { err(1, "create failed"); } - + tprintf("Writing %d bytes.\n", BUFFER_SIZE * BUFFER_COUNT); // 23 Mar 2012 : GWA : Do the even-numbered writes. Test read() and // lseek(SEEK_END). - + for (i = 0; i < BUFFER_COUNT / 2; i++) { for (j = 0; j < BUFFER_SIZE; j++) { writebuf[j] = i * 2 * j; @@ -88,33 +91,33 @@ main(int argc, char **argv) } // 23 Mar 2012 : GWA : Use lseek() to skip the odd guys. - + target = (i + 1) * 2 * sizeof(writebuf); pos = lseek(fh, sizeof(writebuf), SEEK_END); if (pos != target) { err(1, "(even) lseek failed: %llu != %llu", pos, target); } } - + target = 0; pos = lseek(fh, target, SEEK_SET); if (pos != target) { err(1, "(reset) lseek failed: %llu != %llu", pos, target); } - + // 23 Mar 2012 : GWA : Do the odd-numbered writes. Test write() and // lseek(SEEK_CUR). - + for (i = 0; i < BUFFER_COUNT / 2; i++) { - + // 23 Mar 2012 : GWA : Use lseek() to skip the even guys. - + target = ((i * 2) + 1) * sizeof(writebuf); pos = lseek(fh, sizeof(writebuf), SEEK_CUR); if (pos != target) { err(1, "(odd) lseek failed: %llu != %llu", pos, target); } - + for (j = 0; j < BUFFER_SIZE; j++) { writebuf[j] = ((i * 2) + 1) * j; } @@ -123,10 +126,10 @@ main(int argc, char **argv) err(1, "write failed"); } } - + // 23 Mar 2012 : GWA : Read the test data back and make sure what we wrote // ended up where we wrote it. Tests read() and lseek(SEEK_SET). - + tprintf("Verifying write.\n"); for (i = BUFFER_COUNT - 1; i >= 0; i--) { @@ -147,21 +150,19 @@ main(int argc, char **argv) } // 23 Mar 2012 : GWA : Close the file. - + tprintf("Closing %s\n", filename); close(fh); - + // 23 Mar 2012 : GWA : Make sure the file is actually closed. pos = lseek(fh, (off_t) 0, SEEK_SET); if (pos == 0) { err(1, "seek after close succeeded"); } - - // 23 Mar 2012 : GWA : FIXME : Spin until exit() works. - - tprintf("Spinning in case exit() doesn't work.\n"); - while (1) {}; + success(TEST161_SUCCESS, SECRET, "/testbin/fileonlytest"); + // Exit may not be implemented. So crash. + crash_prog(); return 0; } diff --git a/userland/testbin/forktest/forktest.c b/userland/testbin/forktest/forktest.c index 4f7fed3..9283ad0 100644 --- a/userland/testbin/forktest/forktest.c +++ b/userland/testbin/forktest/forktest.c @@ -37,10 +37,16 @@ */ #include +#include #include #include #include #include +#include + +#define FORKTEST_FILENAME_BASE "forktest" + +static char filename[32]; /* * This is used by all processes, to try to help make sure all @@ -48,6 +54,18 @@ */ static volatile int mypid; +/* + * Helper function to do pow() + */ +static +int pow_int(int x, int y) { + int i; + int result = 1; + for(i = 0; i < y; i++) + result *= x; + return result; +} + /* * Helper function for fork that prints a warning on error. */ @@ -141,17 +159,38 @@ test(int nowait) * to prevent wait/exit problems if fork corrupts memory. */ + /* + * Guru: We have a problem here. + * We need to write the output to a file since test161 is + * supposed to be as simple as possible. This requires the + * test to tell test161 whether it passed or succeeded. + * We cannot lseek and read stdout, to check the output, + * so we need to write the output to a file and then check it later. + * + * So far so good. However, if in the future, forktest is + * going to be combined with triple/quint/etc, then the filename + * cannot be the same across multiple copies. So we need a + * unique filename per instance of forktest. + * So... + */ + snprintf(filename, 32, "%s-%d.bin", FORKTEST_FILENAME_BASE, getpid()); + int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); + if(fd < 3) { + // 0, 1, 2 are stdin, stdout, stderr + err(1, "Failed to open file to write data into\n"); + } + pid0 = dofork(); - putchar('A'); + write(fd, "A", 1); check(); pid1 = dofork(); - putchar('B'); + write(fd, "B", 1); check(); pid2 = dofork(); - putchar('C'); + write(fd, "C", 1); check(); pid3 = dofork(); - putchar('D'); + write(fd, "D", 1); check(); /* @@ -163,7 +202,44 @@ test(int nowait) dowait(nowait, pid1); dowait(nowait, pid0); - putchar('\n'); + // Check if file contents are correct + // lseek may not be implemented..so close and reopen + close(fd); + fd = open(filename, O_RDONLY); + if(fd < 3) { + err(1, "Failed to open file for verification\n"); + } + char buffer[30]; + int len; + int char_idx, i; + int observed, expected; + char character = 'A'; + + memset(buffer, 0, 30); + len = read(fd, buffer, 30); + printf("%s\n", buffer); + if(len != 30) { + err(1, "Did not get expected number of characters\n"); + } + // Check if number of instances of each character is correct + // 2As; 4Bs; 8Cs; 16Ds + for(char_idx = 0; char_idx < 4; char_idx++) { + observed = 0; + expected = pow_int(2, char_idx + 1); + for(i = 0; i < 30; i++) { + // In C, char can be directly converted to an ASCII index + // So, A is 65, B is 66, ... + if(buffer[i] == character + char_idx) { + observed++; + } + } + if(observed != expected) { + // Failed + err(1, "Failed! Expected %d%cs..observed: %d\n", expected, character + char_idx, observed); + } + } + success(TEST161_SUCCESS, SECRET, "/testbin/forktest"); + close(fd); } int diff --git a/userland/testbin/opentest/Makefile b/userland/testbin/opentest/Makefile new file mode 100644 index 0000000..58278d3 --- /dev/null +++ b/userland/testbin/opentest/Makefile @@ -0,0 +1,11 @@ +# Makefile for opentest + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=opentest +SRCS=opentest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/opentest/opentest.c b/userland/testbin/opentest/opentest.c new file mode 100644 index 0000000..0859b91 --- /dev/null +++ b/userland/testbin/opentest/opentest.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * consoletest.c + * + * Tests whether console can be written to. + * + * This should run correctly when open and write syscalls are correctly implemented + */ + +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + + // Assume argument passing is *not* supported. + + (void) argc; + (void) argv; + + int fd, fd1; + // Attempt to open a file that we 'know' exists + fd = open("bin/true", O_RDONLY); + if(fd < 0) { + err(-1, "Open syscall failed"); + } + else if(fd < 3) { + warnx("Open syscall returned number used by standard file descriptors (0,1,2)"); + } + + // Attempt to open the same file again. We should get a different fd + fd1 = open("bin/true", O_RDONLY); + if(fd1 < 0) { + err(-1, "Open syscall failed"); + } + else if(fd1 < 3) { + warnx("Open syscall returned number used by standard file descriptors (0,1,2)"); + } + else if(fd1 == fd) { + err(-1, "Open syscall returned same file descriptor for second open() call\n"); + } + + + success(TEST161_SUCCESS, SECRET, "/testbin/opentest"); + + // Exit may not be implemented. So crash. + crash_prog(); + return 0; +} diff --git a/userland/testbin/randcall/main.c b/userland/testbin/randcall/main.c index c2a16b3..5ae1952 100644 --- a/userland/testbin/randcall/main.c +++ b/userland/testbin/randcall/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "extern.h" @@ -162,5 +163,6 @@ main(int argc, char *argv[]) srandom(seed); trycalls(an, dofork, count); + success(TEST161_SUCCESS, SECRET, "/testbin/randcall"); return 0; } diff --git a/userland/testbin/readwritetest/Makefile b/userland/testbin/readwritetest/Makefile new file mode 100644 index 0000000..b8753fb --- /dev/null +++ b/userland/testbin/readwritetest/Makefile @@ -0,0 +1,11 @@ +# Makefile for readwritetest + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=readwritetest +SRCS=readwritetest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/readwritetest/readwritetest.c b/userland/testbin/readwritetest/readwritetest.c new file mode 100644 index 0000000..4d6fa90 --- /dev/null +++ b/userland/testbin/readwritetest/readwritetest.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * readwritetest.c + * + * Tests whether read and write syscalls works + * This should run correctly when open, write and read are + * implemented correctly. + * + * NOTE: While checking, this test only checks the first 31 characters. + */ + +#include +#include +#include +#include +#include +#include + +#define FILENAME "readwritetest.dat" + +static const char *MAGIC = "h4xa0rRq0Vgbc96tiYJ^!#nXzZSAKPO"; + +int +main(int argc, char **argv) +{ + + // 23 Mar 2012 : GWA : Assume argument passing is *not* supported. + + (void) argc; + (void) argv; + + int fd, len; + int expected_len = strlen(MAGIC); + + fd = open(FILENAME, O_WRONLY | O_CREAT | O_TRUNC); + if(fd < 0) { + err(1, "Failed to open file.\n"); + } + + len = write(fd, MAGIC, expected_len); + if(len != expected_len) { + err(1, "writetest expected to write %d bytes to readwritetest.dat." + " Syscall reports that it wrote %d bytes.\n" + "Is your write syscall returning the right value?\n", + expected_len, len); + } + // Now, we test + // close() may not be implemented. + // So just try to open the file again. + fd = open(FILENAME, O_RDONLY); + if(fd < 0) { + err(1, "Failed to open file.\n"); + } + + char buf[32]; + len = read(fd, buf, expected_len); + if(len != 31) { + err(1, "readtest expected to read %d bytes from readtest.dat." + " Only read %d bytes.\n", + expected_len, len); + } + + if(strcmp(MAGIC, buf) != 0) { + err(1, "Did not match MAGIC string.\n" + "MAGIC: %s\n" + "GOT : %s\n", MAGIC, buf); + } + + secprintf(SECRET, MAGIC, "/testbin/readwritetest"); + // Exit may not be implemented. So crash. + crash_prog(); + return 0; +} diff --git a/userland/testbin/redirect/redirect.c b/userland/testbin/redirect/redirect.c index 6125556..71bd288 100644 --- a/userland/testbin/redirect/redirect.c +++ b/userland/testbin/redirect/redirect.c @@ -43,6 +43,7 @@ #include #include #include +#include #define PATH_CAT "/bin/cat" #define INFILE "redirect.in" @@ -59,6 +60,7 @@ doopen(const char *path, int openflags) fd = open(path, openflags, 0664); if (fd < 0) { err(1, "%s", path); + crash_prog(); } return fd; } @@ -75,6 +77,7 @@ dodup2(int ofd, int nfd, const char *file) } if (r != nfd) { errx(1, "%s: dup2: Expected %d, got %d", nfd, r); + crash_prog(); } } @@ -99,10 +102,12 @@ mkfile(void) r = write(fd, slogan, strlen(slogan)); if (r < 0) { err(1, "%s: write", INFILE); + crash_prog(); } if ((size_t)r != strlen(slogan)) { errx(1, "%s: write: Short count (got %zd, expected %zu)", INFILE, r, strlen(slogan)); + crash_prog(); } doclose(fd, INFILE); @@ -121,13 +126,16 @@ chkfile(void) r = read(fd, buf, sizeof(buf)); if (r < 0) { err(1, "%s: read", OUTFILE); + crash_prog(); } if (r == 0) { errx(1, "%s: read: Unexpected EOF", OUTFILE); + crash_prog(); } if ((size_t)r != strlen(slogan)) { errx(1, "%s: read: Short count (got %zd, expected %zu)", OUTFILE, r, strlen(slogan)); + crash_prog(); } doclose(fd, OUTFILE); @@ -147,6 +155,7 @@ cat(void) pid = fork(); if (pid < 0) { err(1, "fork"); + crash_prog(); } if (pid == 0) { @@ -169,12 +178,15 @@ cat(void) result = waitpid(pid, &status, 0); if (result == -1) { err(1, "waitpid"); + crash_prog(); } if (WIFSIGNALED(status)) { errx(1, "pid %d: Signal %d", (int)pid, WTERMSIG(status)); + crash_prog(); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { errx(1, "pid %d: Exit %d", (int)pid, WEXITSTATUS(status)); + crash_prog(); } } @@ -191,6 +203,7 @@ main(void) chkfile(); tprintf("Passed.\n"); + success(TEST161_SUCCESS, SECRET, "/testbin/redirect"); (void)remove(INFILE); (void)remove(OUTFILE); return 0; diff --git a/userland/testbin/shelltest/Makefile b/userland/testbin/shelltest/Makefile new file mode 100644 index 0000000..621862b --- /dev/null +++ b/userland/testbin/shelltest/Makefile @@ -0,0 +1,11 @@ +# Makefile for shelltest + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +PROG=shelltest +SRCS=shelltest.c +BINDIR=/testbin + +.include "$(TOP)/mk/os161.prog.mk" + diff --git a/userland/testbin/shelltest/shelltest.c b/userland/testbin/shelltest/shelltest.c new file mode 100644 index 0000000..63641c5 --- /dev/null +++ b/userland/testbin/shelltest/shelltest.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * shelltest.c + * + * Tests whether console can be written to. + * + * This should run correctly when open and write syscalls are correctly implemented + */ + +#include +#include +#include +#include +#include + +#include + +// 23 Mar 2012 : GWA : BUFFER_COUNT must be even. + +int +main(int argc, char **argv) +{ + + // 23 Mar 2012 : GWA : Assume argument passing is *not* supported. + + (void) argc; + (void) argv; + + int i; + char buf[64]; + for(i = 0; i < 3; i++) { + memset(buf, 0, sizeof(buf)); + snprintf(buf, 64, "line-%d: Able was i ere i saw elbA", i + 1); + secprintf(SECRET, buf, "/testbin/shelltest"); + } + + // Expects exit() to work + return 0; +} diff --git a/userland/testbin/sparsefile/sparsefile.c b/userland/testbin/sparsefile/sparsefile.c index 42e13fb..024f433 100644 --- a/userland/testbin/sparsefile/sparsefile.c +++ b/userland/testbin/sparsefile/sparsefile.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include int main(int argc, char *argv[]) @@ -57,7 +59,7 @@ main(int argc, char *argv[]) filename = argv[1]; size = atoi(argv[2]); - byte = '\n'; + byte = '@'; if (size == 0) { err(1, "Sparse files of length zero are not meaningful"); @@ -65,7 +67,7 @@ main(int argc, char *argv[]) tprintf("Creating a sparse file of size %d\n", size); - fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC); + fd = open(filename, O_RDWR|O_CREAT|O_TRUNC); if (fd < 0) { err(1, "%s: create", filename); } @@ -81,7 +83,26 @@ main(int argc, char *argv[]) errx(1, "%s: write: Unexpected result count %d", filename, r); } + // Now check this byte. + // First seek to the beginning and then seek back to where the byte + // should be. + if(lseek(fd, 0, SEEK_SET) == -1) { + err(1, "lseek failed to seek to beginning of file\n"); + } + // Now seek back to where the byte should be + // While at it, also test SEEK_CUR + if(lseek(fd, size-1, SEEK_CUR) == -1) { + err(1, "lseek failed to seek to %d of file\n", size-1); + } + char test; + r = read(fd, &test, 1); + if(test != byte) { + err(1, "Byte test failed. Expected (%c) != Observed (%c)\n", byte, test); + } close(fd); + success(TEST161_SUCCESS, SECRET, "/testbin/sparsefile"); + // Exit may not be implemented. So crash. + crash_prog(); return 0; }