Added userland/testbin
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -38,6 +38,7 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| 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; | ||||
| } | ||||
|   | ||||
| @@ -36,6 +36,7 @@ | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| 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; | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
| 	} | ||||
|   | ||||
| @@ -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<right_num; i++) { | ||||
| 		if (goterror == right_errors[i]) { | ||||
| 			report_result(rv, error); | ||||
| 			report_passed(); | ||||
| 			return; | ||||
| 			report_passed(&result); | ||||
| 			return result; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (goterror == ENOSYS) { | ||||
| 		report_saw_enosys(); | ||||
| 		say("(unimplemented) "); | ||||
| 		report_skipped(); | ||||
| 		report_skipped(&result); | ||||
| 	} | ||||
| 	else { | ||||
| 		report_result(rv, error); | ||||
| 		report_failure(); | ||||
| 		report_failure(&result); | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void | ||||
| int | ||||
| report_check(int rv, int error, int right_error) | ||||
| { | ||||
| 	report_checkN(rv, error, &right_error, 1); | ||||
| 	return report_checkN(rv, error, &right_error, 1); | ||||
| } | ||||
|  | ||||
| void | ||||
| int | ||||
| report_check2(int rv, int error, int okerr1, int okerr2) | ||||
| { | ||||
| 	int ok[2]; | ||||
|  | ||||
| 	ok[0] = okerr1; | ||||
| 	ok[1] = okerr2; | ||||
| 	report_checkN(rv, error, ok, 2); | ||||
| 	return report_checkN(rv, error, ok, 2); | ||||
| } | ||||
|  | ||||
| void | ||||
| int | ||||
| report_check3(int rv, int error, int okerr1, int okerr2, int okerr3) | ||||
| { | ||||
| 	int ok[3]; | ||||
| @@ -346,5 +352,13 @@ report_check3(int rv, int error, int okerr1, int okerr2, int okerr3) | ||||
| 	ok[0] = okerr1; | ||||
| 	ok[1] = okerr2; | ||||
| 	ok[2] = okerr3; | ||||
| 	report_checkN(rv, error, ok, 3); | ||||
| 	return report_checkN(rv, error, ok, 3); | ||||
| } | ||||
|  | ||||
| void | ||||
| handle_result(int result, int *lost_points) | ||||
| { | ||||
| 	if(result) | ||||
| 		*lost_points = *lost_points + 1; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,8 @@ | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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); | ||||
|  | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
| #include <limits.h> | ||||
| #include <assert.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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"); | ||||
| } | ||||
|   | ||||
							
								
								
									
										11
									
								
								userland/testbin/closetest/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								userland/testbin/closetest/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|  | ||||
							
								
								
									
										81
									
								
								userland/testbin/closetest/closetest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								userland/testbin/closetest/closetest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
|  | ||||
| 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; | ||||
| } | ||||
							
								
								
									
										11
									
								
								userland/testbin/consoletest/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								userland/testbin/consoletest/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|  | ||||
							
								
								
									
										64
									
								
								userland/testbin/consoletest/consoletest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								userland/testbin/consoletest/consoletest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| // 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; | ||||
| } | ||||
| @@ -46,6 +46,8 @@ | ||||
| #include <unistd.h> | ||||
| #include <signal.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
|  | ||||
| #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; | ||||
| } | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
| #include <unistd.h> | ||||
| #include <assert.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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]); | ||||
|   | ||||
| @@ -41,6 +41,9 @@ | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| // 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; | ||||
| } | ||||
|   | ||||
| @@ -37,10 +37,16 @@ | ||||
|  */ | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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 | ||||
|   | ||||
							
								
								
									
										11
									
								
								userland/testbin/opentest/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								userland/testbin/opentest/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|  | ||||
							
								
								
									
										82
									
								
								userland/testbin/opentest/opentest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								userland/testbin/opentest/opentest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| 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; | ||||
| } | ||||
| @@ -30,6 +30,7 @@ | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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; | ||||
| } | ||||
|   | ||||
							
								
								
									
										11
									
								
								userland/testbin/readwritetest/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								userland/testbin/readwritetest/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|  | ||||
							
								
								
									
										101
									
								
								userland/testbin/readwritetest/readwritetest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								userland/testbin/readwritetest/readwritetest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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; | ||||
| } | ||||
| @@ -43,6 +43,7 @@ | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| #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; | ||||
|   | ||||
							
								
								
									
										11
									
								
								userland/testbin/shelltest/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								userland/testbin/shelltest/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|  | ||||
							
								
								
									
										67
									
								
								userland/testbin/shelltest/shelltest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								userland/testbin/shelltest/shelltest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <err.h> | ||||
|  | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| // 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; | ||||
| } | ||||
| @@ -41,6 +41,8 @@ | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <err.h> | ||||
| #include <string.h> | ||||
| #include <test161/test161.h> | ||||
|  | ||||
| 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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user