Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/capsicum-test/capsicum-test.cc
39475 views
1
#include "capsicum-test.h"
2
3
#ifdef __FreeBSD__
4
#include <sys/param.h>
5
#include <sys/proc.h>
6
#include <sys/queue.h>
7
#include <sys/socket.h>
8
#include <sys/sysctl.h>
9
#include <sys/user.h>
10
#include <libprocstat.h>
11
#endif
12
13
#include <stdio.h>
14
#include <string.h>
15
#include <signal.h>
16
17
#include <map>
18
#include <vector>
19
#include <string>
20
21
bool verbose = false;
22
bool tmpdir_on_tmpfs = false;
23
bool force_mt = false;
24
bool force_nofork = false;
25
uid_t other_uid = 0;
26
27
namespace {
28
std::map<std::string, std::string> tmp_paths;
29
}
30
31
const char *TmpFile(const char *p) {
32
std::string pathname(p);
33
if (tmp_paths.find(pathname) == tmp_paths.end()) {
34
std::string fullname = tmpdir + "/" + pathname;
35
tmp_paths[pathname] = fullname;
36
}
37
return tmp_paths[pathname].c_str();
38
}
39
40
char ProcessState(int pid) {
41
#ifdef __linux__
42
// Open the process status file.
43
char s[1024];
44
snprintf(s, sizeof(s), "/proc/%d/status", pid);
45
FILE *f = fopen(s, "r");
46
if (f == NULL) return '\0';
47
48
// Read the file line by line looking for the state line.
49
const char *prompt = "State:\t";
50
while (!feof(f)) {
51
fgets(s, sizeof(s), f);
52
if (!strncmp(s, prompt, strlen(prompt))) {
53
fclose(f);
54
return s[strlen(prompt)];
55
}
56
}
57
fclose(f);
58
return '?';
59
#endif
60
#ifdef __FreeBSD__
61
// First check if the process exists/we have permission to see it. This
62
// Avoids warning messages being printed to stderr by libprocstat.
63
size_t len = 0;
64
int name[4];
65
name[0] = CTL_KERN;
66
name[1] = KERN_PROC;
67
name[2] = KERN_PROC_PID;
68
name[3] = pid;
69
if (sysctl(name, nitems(name), NULL, &len, NULL, 0) < 0 && errno == ESRCH) {
70
if (verbose) fprintf(stderr, "Process %d does not exist\n", pid);
71
return '\0'; // No such process.
72
}
73
unsigned int count = 0;
74
struct procstat *prstat = procstat_open_sysctl();
75
EXPECT_NE(nullptr, prstat) << "procstat_open_sysctl failed.";
76
errno = 0;
77
struct kinfo_proc *p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &count);
78
if (p == NULL || count == 0) {
79
if (verbose) {
80
fprintf(stderr, "procstat_getprocs failed with %p/%d: %s\n", (void *)p,
81
count, strerror(errno));
82
}
83
procstat_close(prstat);
84
return '\0';
85
}
86
char result = '\0';
87
// See state() in bin/ps/print.c
88
switch (p->ki_stat) {
89
case SSTOP:
90
result = 'T';
91
break;
92
case SSLEEP:
93
if (p->ki_tdflags & TDF_SINTR) /* interruptable (long) */
94
result = 'S';
95
else
96
result = 'D';
97
break;
98
case SRUN:
99
case SIDL:
100
result = 'R';
101
break;
102
case SWAIT:
103
case SLOCK:
104
// We treat SWAIT/SLOCK as 'S' here (instead of 'W'/'L').
105
result = 'S';
106
break;
107
case SZOMB:
108
result = 'Z';
109
break;
110
default:
111
result = '?';
112
break;
113
}
114
procstat_freeprocs(prstat, p);
115
procstat_close(prstat);
116
if (verbose) fprintf(stderr, "Process %d in state '%c'\n", pid, result);
117
return result;
118
#endif
119
}
120
121