Blame


1 0a04a7c0 2023-12-19 benni
2 0a04a7c0 2023-12-19 benni static int
3 0a04a7c0 2023-12-19 benni copy_str(const char *field, size_t max, char *buf, size_t size, off_t off)
4 0a04a7c0 2023-12-19 benni {
5 0a04a7c0 2023-12-19 benni const size_t n = strnlen(field, max);
6 0a04a7c0 2023-12-19 benni if ((size_t)off < n) {
7 0a04a7c0 2023-12-19 benni if ((n - off) < size)
8 0a04a7c0 2023-12-19 benni size = n - off;
9 0a04a7c0 2023-12-19 benni memcpy(buf, field + off, size);
10 0a04a7c0 2023-12-19 benni return n - off;
11 0a04a7c0 2023-12-19 benni } else if ((size_t)off > n) {
12 0a04a7c0 2023-12-19 benni return 0;
13 0a04a7c0 2023-12-19 benni } else {
14 0a04a7c0 2023-12-19 benni buf[0] = '\n';
15 0a04a7c0 2023-12-19 benni return 1;
16 0a04a7c0 2023-12-19 benni }
17 0a04a7c0 2023-12-19 benni }
18 0a04a7c0 2023-12-19 benni
19 0a04a7c0 2023-12-19 benni static int
20 0a04a7c0 2023-12-19 benni copy_str2(const char *field, char *buf, size_t size, off_t off)
21 0a04a7c0 2023-12-19 benni {
22 0a04a7c0 2023-12-19 benni const size_t n = strlen(field);
23 0a04a7c0 2023-12-19 benni if ((size_t)off < n) {
24 0a04a7c0 2023-12-19 benni if ((n - off) < size)
25 0a04a7c0 2023-12-19 benni size = n - off;
26 0a04a7c0 2023-12-19 benni memcpy(buf, field + off, size);
27 0a04a7c0 2023-12-19 benni return n - off;
28 0a04a7c0 2023-12-19 benni } else {
29 0a04a7c0 2023-12-19 benni return 0;
30 0a04a7c0 2023-12-19 benni }
31 0a04a7c0 2023-12-19 benni }
32 0a04a7c0 2023-12-19 benni
33 0a04a7c0 2023-12-19 benni static int
34 0a04a7c0 2023-12-19 benni copy_uint(unsigned int field, char *buf, size_t size, off_t off)
35 0a04a7c0 2023-12-19 benni {
36 0a04a7c0 2023-12-19 benni char buffer[32];
37 0a04a7c0 2023-12-19 benni int n;
38 0a04a7c0 2023-12-19 benni
39 0a04a7c0 2023-12-19 benni n = snprintf(buffer, sizeof (buffer), "%u\n", field);
40 0a04a7c0 2023-12-19 benni if (n >= (int)sizeof (buffer)) {
41 0a04a7c0 2023-12-19 benni warnx("copy_uint(%u): Failed to format field.", field);
42 0a04a7c0 2023-12-19 benni return -EIO;
43 0a04a7c0 2023-12-19 benni }
44 0a04a7c0 2023-12-19 benni
45 0a04a7c0 2023-12-19 benni return copy_str2(buffer, buf, size, off);
46 0a04a7c0 2023-12-19 benni }
47 0a04a7c0 2023-12-19 benni
48 0a04a7c0 2023-12-19 benni static int
49 0a04a7c0 2023-12-19 benni copy_int(int field, char *buf, size_t size, off_t off)
50 0a04a7c0 2023-12-19 benni {
51 0a04a7c0 2023-12-19 benni char buffer[32];
52 0a04a7c0 2023-12-19 benni int n;
53 0a04a7c0 2023-12-19 benni
54 0a04a7c0 2023-12-19 benni n = snprintf(buffer, sizeof (buffer), "%d\n", field);
55 0a04a7c0 2023-12-19 benni if (n >= (int)sizeof (buffer)) {
56 0a04a7c0 2023-12-19 benni warnx("copy_int(%u): Failed to format field.", field);
57 0a04a7c0 2023-12-19 benni return -EIO;
58 0a04a7c0 2023-12-19 benni }
59 0a04a7c0 2023-12-19 benni
60 0a04a7c0 2023-12-19 benni return copy_str2(buffer, buf, size, off);
61 0a04a7c0 2023-12-19 benni }
62 0a04a7c0 2023-12-19 benni
63 0a04a7c0 2023-12-19 benni #define def_uint(arg, name, value) \
64 0a04a7c0 2023-12-19 benni static int \
65 0a04a7c0 2023-12-19 benni name(arg, char *buf, size_t size, off_t off) \
66 0a04a7c0 2023-12-19 benni { \
67 0a04a7c0 2023-12-19 benni return copy_uint((value), buf, size, off); \
68 0a04a7c0 2023-12-19 benni }
69 0a04a7c0 2023-12-19 benni
70 0a04a7c0 2023-12-19 benni #define def_int(arg, name, value) \
71 0a04a7c0 2023-12-19 benni static int \
72 0a04a7c0 2023-12-19 benni name(arg, char *buf, size_t size, off_t off) \
73 0a04a7c0 2023-12-19 benni { \
74 0a04a7c0 2023-12-19 benni return copy_int((value), buf, size, off); \
75 0a04a7c0 2023-12-19 benni }
76 0a04a7c0 2023-12-19 benni
77 0a04a7c0 2023-12-19 benni #define def_str(arg, name, value, max) \
78 0a04a7c0 2023-12-19 benni static int \
79 0a04a7c0 2023-12-19 benni name(arg, char *buf, size_t size, off_t off) \
80 0a04a7c0 2023-12-19 benni { \
81 0a04a7c0 2023-12-19 benni return copy_str((value), max, buf, size, off); \
82 0a04a7c0 2023-12-19 benni }
83 0a04a7c0 2023-12-19 benni
84 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_pid, kp->p_pid);
85 0a04a7c0 2023-12-19 benni def_str(struct kinfo_proc *kp, read_comm, kp->p_comm, KI_MAXCOMLEN);
86 0a04a7c0 2023-12-19 benni def_str(struct kinfo_proc *kp, read_name, kp->p_name, KI_MAXCOMLEN);
87 0a04a7c0 2023-12-19 benni def_str(struct kinfo_proc *kp, read_emul, kp->p_emul, KI_EMULNAMELEN);
88 0a04a7c0 2023-12-19 benni def_str(struct kinfo_proc *kp, read_wmesg, kp->p_wmesg, KI_WMESGLEN);
89 0a04a7c0 2023-12-19 benni def_str(struct kinfo_proc *kp, read_login, kp->p_login, KI_MAXLOGNAME);
90 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_uid, kp->p_uid);
91 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_ruid, kp->p_ruid);
92 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_gid, kp->p_gid);
93 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_rgid, kp->p_rgid);
94 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_proc *kp, read_priority, kp->p_priority);
95 0a04a7c0 2023-12-19 benni def_int(struct kinfo_proc *kp, read_nice, kp->p_nice - 20);
96 0a04a7c0 2023-12-19 benni def_int(struct kinfo_proc *kp, read_vm_rssize, kp->p_vm_rssize);
97 0a04a7c0 2023-12-19 benni def_int(struct kinfo_proc *kp, read_vm_tsize, kp->p_vm_tsize);
98 0a04a7c0 2023-12-19 benni def_int(struct kinfo_proc *kp, read_vm_dsize, kp->p_vm_dsize);
99 0a04a7c0 2023-12-19 benni def_int(struct kinfo_proc *kp, read_vm_ssize, kp->p_vm_ssize);
100 0a04a7c0 2023-12-19 benni
101 0a04a7c0 2023-12-19 benni static int
102 0a04a7c0 2023-12-19 benni read_flag(struct kinfo_proc *kp, char *buf, size_t size, off_t off)
103 0a04a7c0 2023-12-19 benni {
104 0a04a7c0 2023-12-19 benni struct flag {
105 0a04a7c0 2023-12-19 benni const char *name;
106 0a04a7c0 2023-12-19 benni uint32_t mask;
107 0a04a7c0 2023-12-19 benni };
108 0a04a7c0 2023-12-19 benni static struct flag flags[] = {
109 0a04a7c0 2023-12-19 benni { .name = "inktr", .mask = P_INKTR, },
110 0a04a7c0 2023-12-19 benni { .name = "profpend", .mask = P_PROFPEND, },
111 0a04a7c0 2023-12-19 benni { .name = "alrmpend", .mask = P_ALRMPEND, },
112 0a04a7c0 2023-12-19 benni { .name = "sigsuspend", .mask = P_SIGSUSPEND, },
113 0a04a7c0 2023-12-19 benni { .name = "cantsleep", .mask = P_CANTSLEEP, },
114 0a04a7c0 2023-12-19 benni { .name = "wsleep", .mask = P_WSLEEP, },
115 0a04a7c0 2023-12-19 benni { .name = "sintr", .mask = P_SINTR, },
116 0a04a7c0 2023-12-19 benni { .name = "system", .mask = P_SYSTEM, },
117 0a04a7c0 2023-12-19 benni { .name = "timeout", .mask = P_TIMEOUT, },
118 0a04a7c0 2023-12-19 benni { .name = "wexit", .mask = P_WEXIT, },
119 0a04a7c0 2023-12-19 benni { .name = "oweupc", .mask = P_OWEUPC, },
120 0a04a7c0 2023-12-19 benni { .name = "suspsingle", .mask = P_SUSPSINGLE, },
121 0a04a7c0 2023-12-19 benni { .name = "continued", .mask = P_CONTINUED, },
122 0a04a7c0 2023-12-19 benni { .name = "thread", .mask = P_THREAD, },
123 0a04a7c0 2023-12-19 benni { .name = "suspsig", .mask = P_SUSPSIG, },
124 0a04a7c0 2023-12-19 benni { .name = "softdep", .mask = P_SOFTDEP, },
125 0a04a7c0 2023-12-19 benni { .name = "cpupeg", .mask = P_CPUPEG, },
126 0a04a7c0 2023-12-19 benni { .name = NULL, .mask = 0, },
127 0a04a7c0 2023-12-19 benni };
128 0a04a7c0 2023-12-19 benni static char buffer[200];
129 0a04a7c0 2023-12-19 benni
130 0a04a7c0 2023-12-19 benni buffer[0] = '\0';
131 0a04a7c0 2023-12-19 benni for (const struct flag *f = flags; f->name != NULL; ++f) {
132 0a04a7c0 2023-12-19 benni if ((kp->p_flag & f->mask) == f->mask) {
133 0a04a7c0 2023-12-19 benni strlcat(buffer, f->name, sizeof (buffer));
134 0a04a7c0 2023-12-19 benni strlcat(buffer, "\n", sizeof (buffer));
135 0a04a7c0 2023-12-19 benni }
136 0a04a7c0 2023-12-19 benni }
137 0a04a7c0 2023-12-19 benni return copy_str2(buffer, buf, size, off);
138 0a04a7c0 2023-12-19 benni }
139 0a04a7c0 2023-12-19 benni
140 0a04a7c0 2023-12-19 benni static int
141 0a04a7c0 2023-12-19 benni read_groups(struct kinfo_proc *kp, char *buf, size_t size, off_t off)
142 0a04a7c0 2023-12-19 benni {
143 0a04a7c0 2023-12-19 benni static char buffer[KI_NGROUPS * 32];
144 0a04a7c0 2023-12-19 benni
145 0a04a7c0 2023-12-19 benni buffer[0] = '\0';
146 0a04a7c0 2023-12-19 benni
147 0a04a7c0 2023-12-19 benni for (int i = 0; i < kp->p_ngroups; ++i) {
148 0a04a7c0 2023-12-19 benni char tmp[32];
149 0a04a7c0 2023-12-19 benni snprintf(tmp, sizeof (tmp), "%u\n", kp->p_groups[i]);
150 0a04a7c0 2023-12-19 benni strlcat(buffer, tmp, sizeof (buffer));
151 0a04a7c0 2023-12-19 benni }
152 0a04a7c0 2023-12-19 benni return copy_str2(buffer, buf, size, off);
153 0a04a7c0 2023-12-19 benni }
154 0a04a7c0 2023-12-19 benni
155 0a04a7c0 2023-12-19 benni static int
156 0a04a7c0 2023-12-19 benni read_status(struct kinfo_proc *kp, char *buf, size_t size, off_t off)
157 0a04a7c0 2023-12-19 benni {
158 0a04a7c0 2023-12-19 benni const char *s;
159 0a04a7c0 2023-12-19 benni switch (kp->p_stat) {
160 0a04a7c0 2023-12-19 benni case SIDL: s = "idle"; break;
161 0a04a7c0 2023-12-19 benni case SRUN: s = "runnable"; break;
162 0a04a7c0 2023-12-19 benni case SSLEEP: s = "sleeping"; break;
163 0a04a7c0 2023-12-19 benni case SSTOP: s = "stopped"; break;
164 0a04a7c0 2023-12-19 benni case SZOMB: s = "zomb"; break; // unused
165 0a04a7c0 2023-12-19 benni case SDEAD: s = "zombie"; break;
166 0a04a7c0 2023-12-19 benni case SONPROC: s = "running"; break;
167 0a04a7c0 2023-12-19 benni default: s = "unknown"; break;
168 0a04a7c0 2023-12-19 benni }
169 0a04a7c0 2023-12-19 benni return copy_str2(s, buf, size, off);
170 0a04a7c0 2023-12-19 benni }
171 0a04a7c0 2023-12-19 benni
172 0a04a7c0 2023-12-19 benni static int
173 0a04a7c0 2023-12-19 benni read_pledge(struct kinfo_proc *kp, char *buf, size_t size, off_t off)
174 0a04a7c0 2023-12-19 benni {
175 0a04a7c0 2023-12-19 benni static char buffer[sizeof (pledgenames) / sizeof (*pledgenames) * 16];
176 0a04a7c0 2023-12-19 benni
177 0a04a7c0 2023-12-19 benni buffer[0] = '\0';
178 0a04a7c0 2023-12-19 benni
179 0a04a7c0 2023-12-19 benni for (int i = 0; pledgenames[i].bits != 0; ++i) {
180 0a04a7c0 2023-12-19 benni const uint64_t mask = pledgenames[i].bits;
181 0a04a7c0 2023-12-19 benni if ((kp->p_pledge & mask) == mask) {
182 0a04a7c0 2023-12-19 benni strlcat(buffer, pledgenames[i].name, sizeof (buffer));
183 0a04a7c0 2023-12-19 benni strlcat(buffer, "\n", sizeof (buffer));
184 0a04a7c0 2023-12-19 benni }
185 0a04a7c0 2023-12-19 benni }
186 0a04a7c0 2023-12-19 benni
187 0a04a7c0 2023-12-19 benni return copy_str2(buffer, buf, size, off);
188 0a04a7c0 2023-12-19 benni }
189 0a04a7c0 2023-12-19 benni
190 0a04a7c0 2023-12-19 benni // TODO: argv, envv, fd
191 0a04a7c0 2023-12-19 benni
192 0a04a7c0 2023-12-19 benni static struct myfile files[] = {
193 0a04a7c0 2023-12-19 benni { .name = "/pid", .read = read_pid, },
194 0a04a7c0 2023-12-19 benni { .name = "/comm", .read = read_comm, },
195 0a04a7c0 2023-12-19 benni { .name = "/name", .read = read_name, },
196 0a04a7c0 2023-12-19 benni { .name = "/emul", .read = read_emul, },
197 0a04a7c0 2023-12-19 benni { .name = "/wmesg", .read = read_wmesg, },
198 0a04a7c0 2023-12-19 benni { .name = "/login", .read = read_login, },
199 0a04a7c0 2023-12-19 benni { .name = "/uid", .read = read_uid, },
200 0a04a7c0 2023-12-19 benni { .name = "/ruid", .read = read_ruid, },
201 0a04a7c0 2023-12-19 benni { .name = "/gid", .read = read_gid, },
202 0a04a7c0 2023-12-19 benni { .name = "/rgid", .read = read_rgid, },
203 0a04a7c0 2023-12-19 benni { .name = "/priority", .read = read_priority, },
204 0a04a7c0 2023-12-19 benni { .name = "/nice", .read = read_nice, },
205 0a04a7c0 2023-12-19 benni { .name = "/vm_rssize", .read = read_vm_rssize, },
206 0a04a7c0 2023-12-19 benni { .name = "/vm_tsize", .read = read_vm_tsize, },
207 0a04a7c0 2023-12-19 benni { .name = "/vm_dsize", .read = read_vm_dsize, },
208 0a04a7c0 2023-12-19 benni { .name = "/vm_ssize", .read = read_vm_ssize, },
209 0a04a7c0 2023-12-19 benni { .name = "/flag", .read = read_flag, },
210 0a04a7c0 2023-12-19 benni { .name = "/groups", .read = read_groups, },
211 0a04a7c0 2023-12-19 benni { .name = "/status", .read = read_status, },
212 0a04a7c0 2023-12-19 benni { .name = "/pledge", .read = read_pledge, },
213 0a04a7c0 2023-12-19 benni { .name = NULL, .read = NULL, },
214 0a04a7c0 2023-12-19 benni };
215 0a04a7c0 2023-12-19 benni
216 0a04a7c0 2023-12-19 benni static int
217 0a04a7c0 2023-12-19 benni read_fd_type(struct kinfo_file *f, char *buf, size_t size, off_t off)
218 0a04a7c0 2023-12-19 benni {
219 0a04a7c0 2023-12-19 benni const char *s;
220 0a04a7c0 2023-12-19 benni switch (f->f_type) {
221 0a04a7c0 2023-12-19 benni case DTYPE_VNODE: s = "vnode\n"; break;
222 0a04a7c0 2023-12-19 benni case DTYPE_SOCKET: s = "socket\n"; break;
223 0a04a7c0 2023-12-19 benni case DTYPE_PIPE: s = "pipe\n"; break;
224 0a04a7c0 2023-12-19 benni case DTYPE_KQUEUE: s = "kqueue\n"; break;
225 0a04a7c0 2023-12-19 benni case DTYPE_DMABUF: s = "dmabuf\n"; break;
226 0a04a7c0 2023-12-19 benni case DTYPE_SYNC: s = "sync\n"; break;
227 0a04a7c0 2023-12-19 benni }
228 0a04a7c0 2023-12-19 benni return copy_str2(s, buf, size, off);
229 0a04a7c0 2023-12-19 benni }
230 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_file *f, read_fd_fd, f->fd_fd);
231 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_file *f, read_fd_pid, f->p_pid);
232 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_file *f, read_fd_uid, f->f_uid);
233 0a04a7c0 2023-12-19 benni def_uint(struct kinfo_file *f, read_fd_gid, f->f_gid);
234 0a04a7c0 2023-12-19 benni def_str(struct kinfo_file *f, read_fd_comm, f->p_comm, KI_MAXCOMLEN);
235 0a04a7c0 2023-12-19 benni
236 0a04a7c0 2023-12-19 benni static struct myfdfile fd_files[] = {
237 0a04a7c0 2023-12-19 benni { .name = "/type", .read = read_fd_type, },
238 0a04a7c0 2023-12-19 benni { .name = "/fd", .read = read_fd_fd, },
239 0a04a7c0 2023-12-19 benni { .name = "/pid", .read = read_fd_pid, },
240 0a04a7c0 2023-12-19 benni { .name = "/uid", .read = read_fd_uid, },
241 0a04a7c0 2023-12-19 benni { .name = "/gid", .read = read_fd_gid, },
242 0a04a7c0 2023-12-19 benni { .name = "/comm", .read = read_fd_comm, },
243 0a04a7c0 2023-12-19 benni { .name = NULL, .read = NULL, },
244 0a04a7c0 2023-12-19 benni };