1 #include "capsicum-test.h" 2 3 #include <stdio.h> 4 #include <string.h> 5 #include <signal.h> 6 7 #include <map> 8 #include <vector> 9 #include <string> 10 11 bool verbose = false; 12 bool tmpdir_on_tmpfs = false; 13 bool force_mt = false; 14 bool force_nofork = false; 15 uid_t other_uid = 0; 16 17 namespace { 18 std::map<std::string, std::string> tmp_paths; 19 } 20 21 const char *TmpFile(const char *p) { 22 std::string pathname(p); 23 if (tmp_paths.find(pathname) == tmp_paths.end()) { 24 std::string fullname = tmpdir + "/" + pathname; 25 tmp_paths[pathname] = fullname; 26 } 27 return tmp_paths[pathname].c_str(); 28 } 29 30 char ProcessState(int pid) { 31 #ifdef __linux__ 32 // Open the process status file. 33 char s[1024]; 34 snprintf(s, sizeof(s), "/proc/%d/status", pid); 35 FILE *f = fopen(s, "r"); 36 if (f == NULL) return '\0'; 37 38 // Read the file line by line looking for the state line. 39 const char *prompt = "State:\t"; 40 while (!feof(f)) { 41 fgets(s, sizeof(s), f); 42 if (!strncmp(s, prompt, strlen(prompt))) { 43 fclose(f); 44 return s[strlen(prompt)]; 45 } 46 } 47 fclose(f); 48 return '?'; 49 #endif 50 #ifdef __FreeBSD__ 51 char buffer[1024]; 52 snprintf(buffer, sizeof(buffer), "ps -p %d -o state | grep -v STAT", pid); 53 sig_t original = signal(SIGCHLD, SIG_IGN); 54 FILE* cmd = popen(buffer, "r"); 55 usleep(50000); // allow any pending SIGCHLD signals to arrive 56 signal(SIGCHLD, original); 57 int result = fgetc(cmd); 58 fclose(cmd); 59 // Map FreeBSD codes to Linux codes. 60 switch (result) { 61 case EOF: 62 return '\0'; 63 case 'D': // disk wait 64 case 'R': // runnable 65 case 'S': // sleeping 66 case 'T': // stopped 67 case 'Z': // zombie 68 return result; 69 case 'W': // idle interrupt thread 70 return 'S'; 71 case 'I': // idle 72 return 'S'; 73 case 'L': // waiting to acquire lock 74 default: 75 return '?'; 76 } 77 #endif 78 } 79 80 typedef std::vector<std::string> TestList; 81 typedef std::map<std::string, TestList*> SkippedTestMap; 82 static SkippedTestMap skipped_tests; 83 void TestSkipped(const char *testcase, const char *test, const std::string& reason) { 84 if (skipped_tests.find(reason) == skipped_tests.end()) { 85 skipped_tests[reason] = new TestList; 86 } 87 std::string testname(testcase); 88 testname += "."; 89 testname += test; 90 skipped_tests[reason]->push_back(testname); 91 } 92 93 void ShowSkippedTests(std::ostream& os) { 94 for (SkippedTestMap::iterator skiplist = skipped_tests.begin(); 95 skiplist != skipped_tests.end(); ++skiplist) { 96 os << "Following tests were skipped because: " << skiplist->first << std::endl; 97 for (size_t ii = 0; ii < skiplist->second->size(); ++ii) { 98 const std::string& testname((*skiplist->second)[ii]); 99 os << " " << testname << std::endl; 100 } 101 } 102 } 103