aboutsummaryrefslogtreecommitdiff
path: root/capsicum-test.cc
diff options
context:
space:
mode:
authorEnji Cooper <ngie@FreeBSD.org>2019-03-12 01:43:01 +0000
committerEnji Cooper <ngie@FreeBSD.org>2019-03-12 01:43:01 +0000
commite5a5dd6cc488f19e182ad3f694957389e4a7d40a (patch)
treedd55863b2c3d3e4a1521acbd751384d128160957 /capsicum-test.cc
downloadsrc-e5a5dd6cc488f19e182ad3f694957389e4a7d40a.tar.gz
src-e5a5dd6cc488f19e182ad3f694957389e4a7d40a.zip
Notes
Diffstat (limited to 'capsicum-test.cc')
-rw-r--r--capsicum-test.cc102
1 files changed, 102 insertions, 0 deletions
diff --git a/capsicum-test.cc b/capsicum-test.cc
new file mode 100644
index 000000000000..24b096ed877c
--- /dev/null
+++ b/capsicum-test.cc
@@ -0,0 +1,102 @@
+#include "capsicum-test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include <map>
+#include <vector>
+#include <string>
+
+bool verbose = false;
+bool tmpdir_on_tmpfs = false;
+bool force_mt = false;
+bool force_nofork = false;
+uid_t other_uid = 0;
+
+namespace {
+std::map<std::string, std::string> tmp_paths;
+}
+
+const char *TmpFile(const char *p) {
+ std::string pathname(p);
+ if (tmp_paths.find(pathname) == tmp_paths.end()) {
+ std::string fullname = tmpdir + "/" + pathname;
+ tmp_paths[pathname] = fullname;
+ }
+ return tmp_paths[pathname].c_str();
+}
+
+char ProcessState(int pid) {
+#ifdef __linux__
+ // Open the process status file.
+ char s[1024];
+ snprintf(s, sizeof(s), "/proc/%d/status", pid);
+ FILE *f = fopen(s, "r");
+ if (f == NULL) return '\0';
+
+ // Read the file line by line looking for the state line.
+ const char *prompt = "State:\t";
+ while (!feof(f)) {
+ fgets(s, sizeof(s), f);
+ if (!strncmp(s, prompt, strlen(prompt))) {
+ fclose(f);
+ return s[strlen(prompt)];
+ }
+ }
+ fclose(f);
+ return '?';
+#endif
+#ifdef __FreeBSD__
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "ps -p %d -o state | grep -v STAT", pid);
+ sig_t original = signal(SIGCHLD, SIG_IGN);
+ FILE* cmd = popen(buffer, "r");
+ usleep(50000); // allow any pending SIGCHLD signals to arrive
+ signal(SIGCHLD, original);
+ int result = fgetc(cmd);
+ fclose(cmd);
+ // Map FreeBSD codes to Linux codes.
+ switch (result) {
+ case EOF:
+ return '\0';
+ case 'D': // disk wait
+ case 'R': // runnable
+ case 'S': // sleeping
+ case 'T': // stopped
+ case 'Z': // zombie
+ return result;
+ case 'W': // idle interrupt thread
+ return 'S';
+ case 'I': // idle
+ return 'S';
+ case 'L': // waiting to acquire lock
+ default:
+ return '?';
+ }
+#endif
+}
+
+typedef std::vector<std::string> TestList;
+typedef std::map<std::string, TestList*> SkippedTestMap;
+static SkippedTestMap skipped_tests;
+void TestSkipped(const char *testcase, const char *test, const std::string& reason) {
+ if (skipped_tests.find(reason) == skipped_tests.end()) {
+ skipped_tests[reason] = new TestList;
+ }
+ std::string testname(testcase);
+ testname += ".";
+ testname += test;
+ skipped_tests[reason]->push_back(testname);
+}
+
+void ShowSkippedTests(std::ostream& os) {
+ for (SkippedTestMap::iterator skiplist = skipped_tests.begin();
+ skiplist != skipped_tests.end(); ++skiplist) {
+ os << "Following tests were skipped because: " << skiplist->first << std::endl;
+ for (size_t ii = 0; ii < skiplist->second->size(); ++ii) {
+ const std::string& testname((*skiplist->second)[ii]);
+ os << " " << testname << std::endl;
+ }
+ }
+}