Commit | Line | Data |
---|---|---|
780d91b3 KM |
1 | /*- |
2 | * Copyright (c) 1982, 1986, 1989, 1993 Regents of the University of California. | |
4a24f1b0 MT |
3 | * All rights reserved. |
4 | * | |
780d91b3 KM |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Mike Karels at Berkeley Software Design, Inc. | |
7 | * | |
dbf0c423 | 8 | * %sccs.include.redist.c% |
4a24f1b0 | 9 | * |
7e024c88 | 10 | * @(#)kern_sysctl.c 7.32 (Berkeley) %G% |
780d91b3 KM |
11 | */ |
12 | ||
13 | /* | |
14 | * sysctl system call. | |
4a24f1b0 MT |
15 | */ |
16 | ||
38a01dbe | 17 | #include <sys/param.h> |
780d91b3 KM |
18 | #include <sys/systm.h> |
19 | #include <sys/malloc.h> | |
38a01dbe | 20 | #include <sys/proc.h> |
780d91b3 KM |
21 | #include <sys/file.h> |
22 | #include <sys/sysctl.h> | |
23 | #include <sys/unistd.h> | |
24 | #include <sys/buf.h> | |
38a01dbe KB |
25 | #include <sys/ioctl.h> |
26 | #include <sys/tty.h> | |
4a24f1b0 | 27 | |
38a01dbe | 28 | #include <vm/vm.h> |
32041eb1 | 29 | |
38a01dbe | 30 | #include <sys/kinfo_proc.h> |
32041eb1 | 31 | |
780d91b3 KM |
32 | sysctlfn kern_sysctl; |
33 | sysctlfn hw_sysctl; | |
34 | extern sysctlfn vm_sysctl; | |
35 | extern sysctlfn fs_sysctl; | |
36 | extern sysctlfn net_sysctl; | |
37 | extern sysctlfn cpu_sysctl; | |
0a4df682 | 38 | |
780d91b3 KM |
39 | /* |
40 | * Locking and stats | |
41 | */ | |
42 | static struct sysctl_lock { | |
43 | int sl_lock; | |
44 | int sl_want; | |
45 | int sl_locked; | |
46 | } memlock; | |
47 | ||
48 | struct sysctl_args { | |
49 | int *name; | |
50 | u_int namelen; | |
51 | void *old; | |
b48024b7 | 52 | size_t *oldlenp; |
780d91b3 | 53 | void *new; |
b48024b7 | 54 | size_t newlen; |
9e97623a | 55 | }; |
780d91b3 | 56 | |
780d91b3 | 57 | sysctl(p, uap, retval) |
8b24ca5d | 58 | struct proc *p; |
780d91b3 | 59 | register struct sysctl_args *uap; |
8b24ca5d KM |
60 | int *retval; |
61 | { | |
780d91b3 KM |
62 | int error, dolock = 1; |
63 | u_int savelen, oldlen = 0; | |
64 | sysctlfn *fn; | |
65 | int name[CTL_MAXNAME]; | |
0a4df682 | 66 | |
780d91b3 KM |
67 | if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) |
68 | return (error); | |
69 | /* | |
70 | * all top-level sysctl names are non-terminal | |
71 | */ | |
72 | if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) | |
73 | return (EINVAL); | |
74 | if (error = copyin(uap->name, &name, uap->namelen * sizeof(int))) | |
75 | return (error); | |
76 | ||
77 | switch (name[0]) { | |
78 | case CTL_KERN: | |
79 | fn = kern_sysctl; | |
80 | if (name[2] != KERN_VNODE) /* XXX */ | |
81 | dolock = 0; | |
0a4df682 | 82 | break; |
780d91b3 KM |
83 | case CTL_HW: |
84 | fn = hw_sysctl; | |
4a24f1b0 | 85 | break; |
780d91b3 KM |
86 | case CTL_VM: |
87 | fn = vm_sysctl; | |
452737be | 88 | break; |
780d91b3 KM |
89 | case CTL_NET: |
90 | fn = net_sysctl; | |
318784c4 | 91 | break; |
780d91b3 KM |
92 | #ifdef notyet |
93 | case CTL_FS: | |
94 | fn = fs_sysctl; | |
15415c71 | 95 | break; |
780d91b3 KM |
96 | case CTL_DEBUG: |
97 | fn = debug_sysctl; | |
61ece7fc | 98 | break; |
780d91b3 KM |
99 | case CTL_MACHDEP: |
100 | fn = cpu_sysctl; | |
61ece7fc | 101 | break; |
780d91b3 | 102 | #endif |
4a24f1b0 | 103 | default: |
780d91b3 | 104 | return (EOPNOTSUPP); |
7acc8d38 | 105 | } |
780d91b3 KM |
106 | |
107 | if (uap->oldlenp && | |
108 | (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen)))) | |
109 | return (error); | |
110 | if (uap->old != NULL) { | |
111 | if (!useracc(uap->old, oldlen, B_WRITE)) | |
112 | return (EFAULT); | |
113 | while (memlock.sl_lock) { | |
114 | memlock.sl_want = 1; | |
115 | sleep((caddr_t)&memlock, PRIBIO+1); | |
116 | memlock.sl_locked++; | |
117 | } | |
118 | memlock.sl_lock = 1; | |
119 | if (dolock) | |
120 | vslock(uap->old, oldlen); | |
121 | savelen = oldlen; | |
2ed8b3ea | 122 | } |
780d91b3 | 123 | error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen, |
0f1d36b0 | 124 | uap->new, uap->newlen, p); |
780d91b3 KM |
125 | if (uap->old != NULL) { |
126 | if (dolock) | |
127 | vsunlock(uap->old, savelen, B_WRITE); | |
128 | memlock.sl_lock = 0; | |
129 | if (memlock.sl_want) { | |
130 | memlock.sl_want = 0; | |
131 | wakeup((caddr_t)&memlock); | |
132 | } | |
4a24f1b0 | 133 | } |
780d91b3 KM |
134 | if (error) |
135 | return (error); | |
136 | if (uap->oldlenp) | |
137 | error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen)); | |
138 | *retval = oldlen; | |
139 | return (0); | |
140 | } | |
141 | ||
142 | /* | |
143 | * Attributes stored in the kernel. | |
144 | */ | |
145 | char hostname[MAXHOSTNAMELEN]; | |
146 | int hostnamelen; | |
147 | long hostid; | |
0f1d36b0 | 148 | int securelevel; |
780d91b3 | 149 | |
0f1d36b0 KM |
150 | /* |
151 | * kernel related system variables. | |
152 | */ | |
153 | kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) | |
780d91b3 KM |
154 | int *name; |
155 | u_int namelen; | |
156 | void *oldp; | |
b48024b7 | 157 | size_t *oldlenp; |
780d91b3 | 158 | void *newp; |
b48024b7 | 159 | size_t newlen; |
0f1d36b0 | 160 | struct proc *p; |
780d91b3 | 161 | { |
0f1d36b0 | 162 | int error, level; |
780d91b3 KM |
163 | extern char ostype[], osrelease[], version[]; |
164 | ||
165 | /* all sysctl names at this level are terminal */ | |
166 | if (namelen != 1 && name[0] != KERN_PROC) | |
167 | return (ENOTDIR); /* overloaded */ | |
168 | ||
169 | switch (name[0]) { | |
170 | case KERN_OSTYPE: | |
171 | return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); | |
172 | case KERN_OSRELEASE: | |
173 | return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); | |
174 | case KERN_OSREV: | |
175 | return (sysctl_rdint(oldp, oldlenp, newp, BSD)); | |
176 | case KERN_VERSION: | |
177 | return (sysctl_rdstring(oldp, oldlenp, newp, version)); | |
178 | case KERN_POSIX1: | |
179 | return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); | |
180 | case KERN_MAXPROC: | |
181 | return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); | |
182 | case KERN_MAXFILES: | |
183 | return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); | |
184 | case KERN_ARGMAX: | |
185 | return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); | |
186 | case KERN_HOSTNAME: | |
187 | error = sysctl_string(oldp, oldlenp, newp, newlen, | |
188 | hostname, sizeof(hostname)); | |
189 | if (!error) | |
190 | hostnamelen = newlen; | |
191 | return (error); | |
192 | case KERN_HOSTID: | |
193 | return (sysctl_int(oldp, oldlenp, newp, newlen, &hostid)); | |
0f1d36b0 KM |
194 | case KERN_SECURELVL: |
195 | level = securelevel; | |
196 | if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || | |
197 | newp == NULL) | |
198 | return (error); | |
199 | if (level < securelevel && p->p_pid != 1) | |
200 | return (EPERM); | |
201 | securelevel = level; | |
202 | return (0); | |
780d91b3 KM |
203 | case KERN_CLOCKRATE: |
204 | return (sysctl_clockrate(oldp, oldlenp)); | |
205 | case KERN_FILE: | |
206 | return (sysctl_file(oldp, oldlenp)); | |
207 | case KERN_VNODE: | |
208 | return (sysctl_vnode(oldp, oldlenp)); | |
209 | case KERN_PROC: | |
210 | return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); | |
211 | default: | |
212 | return (EOPNOTSUPP); | |
213 | } | |
214 | /* NOTREACHED */ | |
215 | } | |
216 | ||
0f1d36b0 KM |
217 | /* |
218 | * hardware related system variables. | |
219 | */ | |
220 | hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) | |
780d91b3 KM |
221 | int *name; |
222 | u_int namelen; | |
223 | void *oldp; | |
b48024b7 | 224 | size_t *oldlenp; |
780d91b3 | 225 | void *newp; |
b48024b7 | 226 | size_t newlen; |
0f1d36b0 | 227 | struct proc *p; |
780d91b3 KM |
228 | { |
229 | extern char machine[], cpu_model[]; | |
230 | ||
231 | /* all sysctl names at this level are terminal */ | |
232 | if (namelen != 1) | |
233 | return (ENOTDIR); /* overloaded */ | |
234 | ||
235 | switch (name[0]) { | |
236 | case HW_MACHINE: | |
237 | return (sysctl_rdstring(oldp, oldlenp, newp, machine)); | |
238 | case HW_MODEL: | |
239 | return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); | |
240 | case HW_NCPU: | |
241 | return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ | |
242 | case HW_CPUSPEED: | |
243 | return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); | |
244 | case HW_PHYSMEM: | |
245 | return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); | |
246 | case HW_USERMEM: | |
247 | return (sysctl_rdint(oldp, oldlenp, newp, | |
248 | ctob(physmem - cnt.v_wire_count))); | |
249 | case HW_PAGESIZE: | |
250 | return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); | |
251 | default: | |
252 | return (EOPNOTSUPP); | |
253 | } | |
254 | /* NOTREACHED */ | |
255 | } | |
256 | ||
257 | /* | |
258 | * Validate parameters and get old / set new parameters | |
259 | * for an integer-valued sysctl function. | |
260 | */ | |
261 | sysctl_int(oldp, oldlenp, newp, newlen, valp) | |
262 | void *oldp; | |
b48024b7 | 263 | size_t *oldlenp; |
780d91b3 | 264 | void *newp; |
b48024b7 | 265 | size_t newlen; |
780d91b3 KM |
266 | int *valp; |
267 | { | |
268 | int error = 0; | |
269 | ||
270 | if (oldp && *oldlenp < sizeof(int)) | |
271 | return (ENOMEM); | |
272 | if (newp && newlen != sizeof(int)) | |
273 | return (EINVAL); | |
274 | *oldlenp = sizeof(int); | |
275 | if (oldp) | |
276 | error = copyout(valp, oldp, sizeof(int)); | |
277 | if (error == 0 && newp) | |
278 | error = copyin(newp, valp, sizeof(int)); | |
279 | return (error); | |
280 | } | |
281 | ||
282 | /* | |
283 | * As above, but read-only. | |
284 | */ | |
285 | sysctl_rdint(oldp, oldlenp, newp, val) | |
286 | void *oldp; | |
b48024b7 | 287 | size_t *oldlenp; |
780d91b3 KM |
288 | void *newp; |
289 | int val; | |
290 | { | |
291 | int error = 0; | |
292 | ||
293 | if (oldp && *oldlenp < sizeof(int)) | |
294 | return (ENOMEM); | |
295 | if (newp) | |
296 | return (EPERM); | |
297 | *oldlenp = sizeof(int); | |
298 | if (oldp) | |
299 | error = copyout((caddr_t)&val, oldp, sizeof(int)); | |
300 | return (error); | |
301 | } | |
302 | ||
303 | /* | |
304 | * Validate parameters and get old / set new parameters | |
305 | * for a string-valued sysctl function. | |
306 | */ | |
307 | sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) | |
308 | void *oldp; | |
b48024b7 | 309 | size_t *oldlenp; |
780d91b3 | 310 | void *newp; |
b48024b7 | 311 | size_t newlen; |
780d91b3 KM |
312 | char *str; |
313 | int maxlen; | |
314 | { | |
315 | int len, error = 0; | |
316 | ||
317 | len = strlen(str) + 1; | |
318 | if (oldp && *oldlenp < len) | |
319 | return (ENOMEM); | |
320 | if (newp && newlen >= maxlen) | |
321 | return (EINVAL); | |
924ae1bd RC |
322 | if (oldp) { |
323 | *oldlenp = len; | |
780d91b3 | 324 | error = copyout(str, oldp, len); |
924ae1bd | 325 | } |
780d91b3 KM |
326 | if (error == 0 && newp) { |
327 | error = copyin(newp, str, newlen); | |
328 | str[newlen] = 0; | |
13bbbe63 | 329 | } |
8b24ca5d | 330 | return (error); |
4a24f1b0 MT |
331 | } |
332 | ||
780d91b3 KM |
333 | /* |
334 | * As above, but read-only. | |
335 | */ | |
336 | sysctl_rdstring(oldp, oldlenp, newp, str) | |
337 | void *oldp; | |
b48024b7 | 338 | size_t *oldlenp; |
780d91b3 KM |
339 | void *newp; |
340 | char *str; | |
341 | { | |
342 | int len, error = 0; | |
343 | ||
344 | len = strlen(str) + 1; | |
345 | if (oldp && *oldlenp < len) | |
346 | return (ENOMEM); | |
347 | if (newp) | |
348 | return (EPERM); | |
349 | *oldlenp = len; | |
350 | if (oldp) | |
351 | error = copyout(str, oldp, len); | |
352 | return (error); | |
353 | } | |
354 | ||
355 | /* | |
356 | * Validate parameters and get old parameters | |
357 | * for a structure oriented sysctl function. | |
358 | */ | |
359 | sysctl_rdstruct(oldp, oldlenp, newp, sp, len) | |
360 | void *oldp; | |
b48024b7 KB |
361 | size_t *oldlenp; |
362 | void *newp, *sp; | |
780d91b3 KM |
363 | int len; |
364 | { | |
365 | int error = 0; | |
366 | ||
367 | if (oldp && *oldlenp < len) | |
368 | return (ENOMEM); | |
369 | if (newp) | |
370 | return (EPERM); | |
371 | *oldlenp = len; | |
372 | if (oldp) | |
373 | error = copyout(sp, oldp, len); | |
374 | return (error); | |
375 | } | |
376 | ||
377 | /* | |
378 | * Get file structures. | |
379 | */ | |
380 | sysctl_file(where, sizep) | |
381 | char *where; | |
b48024b7 | 382 | size_t *sizep; |
780d91b3 KM |
383 | { |
384 | int buflen, error; | |
385 | struct file *fp; | |
386 | char *start = where; | |
387 | ||
388 | buflen = *sizep; | |
389 | if (where == NULL) { | |
390 | /* | |
391 | * overestimate by 10 files | |
392 | */ | |
393 | *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); | |
394 | return (0); | |
395 | } | |
396 | ||
397 | /* | |
398 | * first copyout filehead | |
399 | */ | |
400 | if (buflen < sizeof(filehead)) { | |
401 | *sizep = 0; | |
402 | return (0); | |
403 | } | |
404 | if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) | |
405 | return (error); | |
406 | buflen += sizeof(filehead); | |
407 | where += sizeof(filehead); | |
408 | ||
409 | /* | |
410 | * followed by an array of file structures | |
411 | */ | |
412 | for (fp = filehead; fp != NULL; fp = fp->f_filef) { | |
413 | if (buflen < sizeof(struct file)) { | |
414 | *sizep = where - start; | |
415 | return (ENOMEM); | |
416 | } | |
417 | if (error = copyout((caddr_t)fp, where, sizeof (struct file))) | |
418 | return (error); | |
419 | buflen -= sizeof(struct file); | |
420 | where += sizeof(struct file); | |
421 | } | |
422 | *sizep = where - start; | |
423 | return (0); | |
424 | } | |
425 | ||
4a24f1b0 MT |
426 | /* |
427 | * try over estimating by 5 procs | |
428 | */ | |
780d91b3 | 429 | #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) |
4a24f1b0 | 430 | |
780d91b3 KM |
431 | sysctl_doproc(name, namelen, where, sizep) |
432 | int *name; | |
b48024b7 | 433 | u_int namelen; |
4a24f1b0 | 434 | char *where; |
b48024b7 | 435 | size_t *sizep; |
4a24f1b0 MT |
436 | { |
437 | register struct proc *p; | |
a65b44f0 | 438 | register struct kinfo_proc *dp = (struct kinfo_proc *)where; |
780d91b3 KM |
439 | register int needed = 0; |
440 | int buflen = where != NULL ? *sizep : 0; | |
4a24f1b0 | 441 | int doingzomb; |
7747bd3b | 442 | struct eproc eproc; |
4a24f1b0 MT |
443 | int error = 0; |
444 | ||
780d91b3 KM |
445 | if (namelen != 2) |
446 | return (EINVAL); | |
80a8e5e6 | 447 | p = (struct proc *)allproc; |
4a24f1b0 MT |
448 | doingzomb = 0; |
449 | again: | |
450 | for (; p != NULL; p = p->p_nxt) { | |
02ea4076 KM |
451 | /* |
452 | * Skip embryonic processes. | |
453 | */ | |
454 | if (p->p_stat == SIDL) | |
455 | continue; | |
4a24f1b0 MT |
456 | /* |
457 | * TODO - make more efficient (see notes below). | |
458 | * do by session. | |
459 | */ | |
780d91b3 | 460 | switch (name[0]) { |
4a24f1b0 | 461 | |
780d91b3 | 462 | case KERN_PROC_PID: |
4a24f1b0 | 463 | /* could do this with just a lookup */ |
780d91b3 | 464 | if (p->p_pid != (pid_t)name[1]) |
4a24f1b0 MT |
465 | continue; |
466 | break; | |
467 | ||
780d91b3 | 468 | case KERN_PROC_PGRP: |
4a24f1b0 | 469 | /* could do this by traversing pgrp */ |
780d91b3 | 470 | if (p->p_pgrp->pg_id != (pid_t)name[1]) |
4a24f1b0 MT |
471 | continue; |
472 | break; | |
473 | ||
780d91b3 | 474 | case KERN_PROC_TTY: |
4a24f1b0 MT |
475 | if ((p->p_flag&SCTTY) == 0 || |
476 | p->p_session->s_ttyp == NULL || | |
780d91b3 | 477 | p->p_session->s_ttyp->t_dev != (dev_t)name[1]) |
4a24f1b0 MT |
478 | continue; |
479 | break; | |
480 | ||
780d91b3 KM |
481 | case KERN_PROC_UID: |
482 | if (p->p_ucred->cr_uid != (uid_t)name[1]) | |
4a24f1b0 MT |
483 | continue; |
484 | break; | |
485 | ||
780d91b3 KM |
486 | case KERN_PROC_RUID: |
487 | if (p->p_cred->p_ruid != (uid_t)name[1]) | |
4a24f1b0 MT |
488 | continue; |
489 | break; | |
490 | } | |
780d91b3 | 491 | if (buflen >= sizeof(struct kinfo_proc)) { |
32041eb1 | 492 | fill_eproc(p, &eproc); |
a65b44f0 | 493 | if (error = copyout((caddr_t)p, &dp->kp_proc, |
780d91b3 | 494 | sizeof(struct proc))) |
4a24f1b0 | 495 | return (error); |
a65b44f0 | 496 | if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, |
780d91b3 | 497 | sizeof(eproc))) |
4a24f1b0 | 498 | return (error); |
a65b44f0 | 499 | dp++; |
780d91b3 | 500 | buflen -= sizeof(struct kinfo_proc); |
4a24f1b0 | 501 | } |
780d91b3 | 502 | needed += sizeof(struct kinfo_proc); |
4a24f1b0 MT |
503 | } |
504 | if (doingzomb == 0) { | |
505 | p = zombproc; | |
506 | doingzomb++; | |
507 | goto again; | |
508 | } | |
780d91b3 KM |
509 | if (where != NULL) { |
510 | *sizep = (caddr_t)dp - where; | |
511 | if (needed > *sizep) | |
512 | return (ENOMEM); | |
513 | } else { | |
514 | needed += KERN_PROCSLOP; | |
515 | *sizep = needed; | |
516 | } | |
4a24f1b0 MT |
517 | return (0); |
518 | } | |
32041eb1 MK |
519 | |
520 | /* | |
521 | * Fill in an eproc structure for the specified process. | |
522 | */ | |
523 | void | |
524 | fill_eproc(p, ep) | |
525 | register struct proc *p; | |
526 | register struct eproc *ep; | |
527 | { | |
528 | register struct tty *tp; | |
529 | ||
530 | ep->e_paddr = p; | |
531 | ep->e_sess = p->p_pgrp->pg_session; | |
532 | ep->e_pcred = *p->p_cred; | |
533 | ep->e_ucred = *p->p_ucred; | |
13bbbe63 CT |
534 | if (p->p_stat == SIDL || p->p_stat == SZOMB) { |
535 | ep->e_vm.vm_rssize = 0; | |
536 | ep->e_vm.vm_tsize = 0; | |
537 | ep->e_vm.vm_dsize = 0; | |
538 | ep->e_vm.vm_ssize = 0; | |
539 | #ifndef sparc | |
540 | /* ep->e_vm.vm_pmap = XXX; */ | |
541 | #endif | |
542 | } else { | |
543 | register struct vmspace *vm = p->p_vmspace; | |
544 | ||
545 | ep->e_vm.vm_rssize = vm->vm_rssize; | |
546 | ep->e_vm.vm_tsize = vm->vm_tsize; | |
547 | ep->e_vm.vm_dsize = vm->vm_dsize; | |
548 | ep->e_vm.vm_ssize = vm->vm_ssize; | |
549 | #ifndef sparc | |
550 | ep->e_vm.vm_pmap = vm->vm_pmap; | |
551 | #endif | |
552 | } | |
31c481fa MK |
553 | if (p->p_pptr) |
554 | ep->e_ppid = p->p_pptr->p_pid; | |
555 | else | |
556 | ep->e_ppid = 0; | |
32041eb1 MK |
557 | ep->e_pgid = p->p_pgrp->pg_id; |
558 | ep->e_jobc = p->p_pgrp->pg_jobc; | |
559 | if ((p->p_flag&SCTTY) && | |
560 | (tp = ep->e_sess->s_ttyp)) { | |
561 | ep->e_tdev = tp->t_dev; | |
51d82109 | 562 | ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; |
32041eb1 MK |
563 | ep->e_tsess = tp->t_session; |
564 | } else | |
565 | ep->e_tdev = NODEV; | |
566 | ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; | |
567 | if (SESS_LEADER(p)) | |
568 | ep->e_flag |= EPROC_SLEADER; | |
569 | if (p->p_wmesg) | |
570 | strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); | |
571 | ep->e_xsize = ep->e_xrssize = 0; | |
572 | ep->e_xccount = ep->e_xswrss = 0; | |
573 | } | |
318784c4 | 574 | |
780d91b3 | 575 | #ifdef COMPAT_43 |
780d91b3 | 576 | #include <sys/socket.h> |
1fa29dab KM |
577 | #define KINFO_PROC (0<<8) |
578 | #define KINFO_RT (1<<8) | |
579 | #define KINFO_VNODE (2<<8) | |
580 | #define KINFO_FILE (3<<8) | |
581 | #define KINFO_METER (4<<8) | |
582 | #define KINFO_LOADAVG (5<<8) | |
583 | #define KINFO_CLOCKRATE (6<<8) | |
780d91b3 KM |
584 | |
585 | struct getkerninfo_args { | |
586 | int op; | |
587 | char *where; | |
588 | int *size; | |
589 | int arg; | |
590 | }; | |
591 | ||
7e024c88 | 592 | ogetkerninfo(p, uap, retval) |
780d91b3 KM |
593 | struct proc *p; |
594 | register struct getkerninfo_args *uap; | |
595 | int *retval; | |
318784c4 | 596 | { |
780d91b3 KM |
597 | int error, name[5]; |
598 | u_int size; | |
318784c4 | 599 | |
358fe79a | 600 | if (uap->size && |
b48024b7 | 601 | (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size)))) |
780d91b3 | 602 | return (error); |
318784c4 | 603 | |
1fa29dab | 604 | switch (uap->op & 0xff00) { |
318784c4 | 605 | |
780d91b3 KM |
606 | case KINFO_RT: |
607 | name[0] = PF_ROUTE; | |
608 | name[1] = 0; | |
609 | name[2] = (uap->op & 0xff0000) >> 16; | |
610 | name[3] = uap->op & 0xff; | |
611 | name[4] = uap->arg; | |
0f1d36b0 | 612 | error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p); |
780d91b3 | 613 | break; |
318784c4 | 614 | |
780d91b3 KM |
615 | case KINFO_VNODE: |
616 | name[0] = KERN_VNODE; | |
0f1d36b0 | 617 | error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
618 | break; |
619 | ||
620 | case KINFO_PROC: | |
621 | name[0] = KERN_PROC; | |
622 | name[1] = uap->op & 0xff; | |
623 | name[2] = uap->arg; | |
0f1d36b0 | 624 | error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
625 | break; |
626 | ||
627 | case KINFO_FILE: | |
628 | name[0] = KERN_FILE; | |
0f1d36b0 | 629 | error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
630 | break; |
631 | ||
632 | case KINFO_METER: | |
633 | name[0] = VM_METER; | |
0f1d36b0 | 634 | error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
635 | break; |
636 | ||
637 | case KINFO_LOADAVG: | |
638 | name[0] = VM_LOADAVG; | |
0f1d36b0 | 639 | error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
640 | break; |
641 | ||
642 | case KINFO_CLOCKRATE: | |
643 | name[0] = KERN_CLOCKRATE; | |
0f1d36b0 | 644 | error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); |
780d91b3 KM |
645 | break; |
646 | ||
647 | default: | |
0f1d36b0 | 648 | return (EOPNOTSUPP); |
780d91b3 KM |
649 | } |
650 | if (error) | |
651 | return (error); | |
652 | *retval = size; | |
358fe79a KM |
653 | if (uap->size) |
654 | error = copyout((caddr_t)&size, (caddr_t)uap->size, | |
655 | sizeof(size)); | |
656 | return (error); | |
318784c4 | 657 | } |
780d91b3 | 658 | #endif /* COMPAT_43 */ |