aboutsummaryrefslogtreecommitdiff
path: root/tools/regression/security/cap_test/cap_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/regression/security/cap_test/cap_test.c')
-rw-r--r--tools/regression/security/cap_test/cap_test.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/tools/regression/security/cap_test/cap_test.c b/tools/regression/security/cap_test/cap_test.c
index 5a2dc15532ea..fb3440672337 100644
--- a/tools/regression/security/cap_test/cap_test.c
+++ b/tools/regression/security/cap_test/cap_test.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2008-2011 Robert N. M. Watson
+ * Copyright (c) 2011 Jonathan Anderson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,19 +30,89 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/wait.h>
+
+#include <err.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include "cap_test.h"
+/* Initialize a named test. Requires test_NAME() function to be declared. */
+#define TEST_INIT(name) { #name, test_##name, FAILED }
+
+/* All of the tests that can be run. */
+struct test all_tests[] = {
+ TEST_INIT(capmode),
+ TEST_INIT(capabilities),
+ TEST_INIT(fcntl),
+ TEST_INIT(sysctl),
+};
+size_t test_count = sizeof(all_tests) / sizeof(struct test);
+
int
main(int argc, char *argv[])
{
- test_capmode();
- test_sysctl();
+
/*
- test_capabilities();
- test_syscalls();
- test_fcntl();
- */
- exit(0);
+ * If no tests have been specified at the command line, run them all.
+ */
+ if (argc == 1) {
+ printf("1..%ld\n", test_count);
+
+ for (size_t i = 0; i < test_count; i++)
+ execute(i + 1, all_tests + i);
+ return (0);
+ }
+
+ /*
+ * Otherwise, run only the specified tests.
+ */
+ printf("1..%d\n", argc - 1);
+ for (int i = 1; i < argc; i++)
+ {
+ int found = 0;
+ for (size_t j = 0; j < test_count; j++) {
+ if (strncmp(argv[i], all_tests[j].t_name,
+ strlen(argv[i])) == 0) {
+ found = 1;
+ execute(i, all_tests + j);
+ break;
+ }
+ }
+
+ if (found == 0)
+ errx(-1, "No such test '%s'", argv[i]);
+ }
+
+ return (0);
+}
+
+int
+execute(int id, struct test *t) {
+ int result;
+
+ pid_t pid = fork();
+ if (pid < 0)
+ err(-1, "fork");
+ if (pid) {
+ /* Parent: wait for result from child. */
+ int status;
+ while (waitpid(pid, &status, 0) != pid) {}
+ if (WIFEXITED(status))
+ result = WEXITSTATUS(status);
+ else
+ result = FAILED;
+ } else {
+ /* Child process: run the test. */
+ exit(t->t_run());
+ }
+
+ printf("%s %d - %s\n",
+ (result == PASSED) ? "ok" : "not ok",
+ id, t->t_name);
+
+ return (result);
}