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 | * |
0f1d36b0 | 10 | * @(#)kern_sysctl.c 7.29 (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; | |
52 | u_int *oldlenp; | |
53 | void *new; | |
54 | u_int 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; | |
157 | u_int *oldlenp; | |
158 | void *newp; | |
159 | u_int 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; | |
224 | u_int *oldlenp; | |
225 | void *newp; | |
226 | u_int 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; | |
263 | u_int *oldlenp; | |
264 | void *newp; | |
265 | u_int newlen; | |
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; | |
287 | u_int *oldlenp; | |
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; | |
309 | u_int *oldlenp; | |
310 | void *newp; | |
311 | u_int newlen; | |
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; | |
338 | u_int *oldlenp; | |
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; | |
361 | u_int *oldlenp; | |
362 | void *newp; | |
363 | void *sp; | |
364 | int len; | |
365 | { | |
366 | int error = 0; | |
367 | ||
368 | if (oldp && *oldlenp < len) | |
369 | return (ENOMEM); | |
370 | if (newp) | |
371 | return (EPERM); | |
372 | *oldlenp = len; | |
373 | if (oldp) | |
374 | error = copyout(sp, oldp, len); | |
375 | return (error); | |
376 | } | |
377 | ||
378 | /* | |
379 | * Get file structures. | |
380 | */ | |
381 | sysctl_file(where, sizep) | |
382 | char *where; | |
383 | int *sizep; | |
384 | { | |
385 | int buflen, error; | |
386 | struct file *fp; | |
387 | char *start = where; | |
388 | ||
389 | buflen = *sizep; | |
390 | if (where == NULL) { | |
391 | /* | |
392 | * overestimate by 10 files | |
393 | */ | |
394 | *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); | |
395 | return (0); | |
396 | } | |
397 | ||
398 | /* | |
399 | * first copyout filehead | |
400 | */ | |
401 | if (buflen < sizeof(filehead)) { | |
402 | *sizep = 0; | |
403 | return (0); | |
404 | } | |
405 | if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) | |
406 | return (error); | |
407 | buflen += sizeof(filehead); | |
408 | where += sizeof(filehead); | |
409 | ||
410 | /* | |
411 | * followed by an array of file structures | |
412 | */ | |
413 | for (fp = filehead; fp != NULL; fp = fp->f_filef) { | |
414 | if (buflen < sizeof(struct file)) { | |
415 | *sizep = where - start; | |
416 | return (ENOMEM); | |
417 | } | |
418 | if (error = copyout((caddr_t)fp, where, sizeof (struct file))) | |
419 | return (error); | |
420 | buflen -= sizeof(struct file); | |
421 | where += sizeof(struct file); | |
422 | } | |
423 | *sizep = where - start; | |
424 | return (0); | |
425 | } | |
426 | ||
4a24f1b0 MT |
427 | /* |
428 | * try over estimating by 5 procs | |
429 | */ | |
780d91b3 | 430 | #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) |
4a24f1b0 | 431 | |
780d91b3 KM |
432 | sysctl_doproc(name, namelen, where, sizep) |
433 | int *name; | |
434 | int namelen; | |
4a24f1b0 | 435 | char *where; |
780d91b3 | 436 | int *sizep; |
4a24f1b0 MT |
437 | { |
438 | register struct proc *p; | |
a65b44f0 | 439 | register struct kinfo_proc *dp = (struct kinfo_proc *)where; |
780d91b3 KM |
440 | register int needed = 0; |
441 | int buflen = where != NULL ? *sizep : 0; | |
4a24f1b0 | 442 | int doingzomb; |
7747bd3b | 443 | struct eproc eproc; |
4a24f1b0 MT |
444 | int error = 0; |
445 | ||
780d91b3 KM |
446 | if (namelen != 2) |
447 | return (EINVAL); | |
80a8e5e6 | 448 | p = (struct proc *)allproc; |
4a24f1b0 MT |
449 | doingzomb = 0; |
450 | again: | |
451 | for (; p != NULL; p = p->p_nxt) { | |
02ea4076 KM |
452 | /* |
453 | * Skip embryonic processes. | |
454 | */ | |
455 | if (p->p_stat == SIDL) | |
456 | continue; | |
4a24f1b0 MT |
457 | /* |
458 | * TODO - make more efficient (see notes below). | |
459 | * do by session. | |
460 | */ | |
780d91b3 | 461 | switch (name[0]) { |
4a24f1b0 | 462 | |
780d91b3 | 463 | case KERN_PROC_PID: |
4a24f1b0 | 464 | /* could do this with just a lookup */ |
780d91b3 | 465 | if (p->p_pid != (pid_t)name[1]) |
4a24f1b0 MT |
466 | continue; |
467 | break; | |
468 | ||
780d91b3 | 469 | case KERN_PROC_PGRP: |
4a24f1b0 | 470 | /* could do this by traversing pgrp */ |
780d91b3 | 471 | if (p->p_pgrp->pg_id != (pid_t)name[1]) |
4a24f1b0 MT |
472 | continue; |
473 | break; | |
474 | ||
780d91b3 | 475 | case KERN_PROC_TTY: |
4a24f1b0 MT |
476 | if ((p->p_flag&SCTTY) == 0 || |
477 | p->p_session->s_ttyp == NULL || | |
780d91b3 | 478 | p->p_session->s_ttyp->t_dev != (dev_t)name[1]) |
4a24f1b0 MT |
479 | continue; |
480 | break; | |
481 | ||
780d91b3 KM |
482 | case KERN_PROC_UID: |
483 | if (p->p_ucred->cr_uid != (uid_t)name[1]) | |
4a24f1b0 MT |
484 | continue; |
485 | break; | |
486 | ||
780d91b3 KM |
487 | case KERN_PROC_RUID: |
488 | if (p->p_cred->p_ruid != (uid_t)name[1]) | |
4a24f1b0 MT |
489 | continue; |
490 | break; | |
491 | } | |
780d91b3 | 492 | if (buflen >= sizeof(struct kinfo_proc)) { |
32041eb1 | 493 | fill_eproc(p, &eproc); |
a65b44f0 | 494 | if (error = copyout((caddr_t)p, &dp->kp_proc, |
780d91b3 | 495 | sizeof(struct proc))) |
4a24f1b0 | 496 | return (error); |
a65b44f0 | 497 | if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, |
780d91b3 | 498 | sizeof(eproc))) |
4a24f1b0 | 499 | return (error); |
a65b44f0 | 500 | dp++; |
780d91b3 | 501 | buflen -= sizeof(struct kinfo_proc); |
4a24f1b0 | 502 | } |
780d91b3 | 503 | needed += sizeof(struct kinfo_proc); |
4a24f1b0 MT |
504 | } |
505 | if (doingzomb == 0) { | |
506 | p = zombproc; | |
507 | doingzomb++; | |
508 | goto again; | |
509 | } | |
780d91b3 KM |
510 | if (where != NULL) { |
511 | *sizep = (caddr_t)dp - where; | |
512 | if (needed > *sizep) | |
513 | return (ENOMEM); | |
514 | } else { | |
515 | needed += KERN_PROCSLOP; | |
516 | *sizep = needed; | |
517 | } | |
4a24f1b0 MT |
518 | return (0); |
519 | } | |
32041eb1 MK |
520 | |
521 | /* | |
522 | * Fill in an eproc structure for the specified process. | |
523 | */ | |
524 | void | |
525 | fill_eproc(p, ep) | |
526 | register struct proc *p; | |
527 | register struct eproc *ep; | |
528 | { | |
529 | register struct tty *tp; | |
530 | ||
531 | ep->e_paddr = p; | |
532 | ep->e_sess = p->p_pgrp->pg_session; | |
533 | ep->e_pcred = *p->p_cred; | |
534 | ep->e_ucred = *p->p_ucred; | |
13bbbe63 CT |
535 | if (p->p_stat == SIDL || p->p_stat == SZOMB) { |
536 | ep->e_vm.vm_rssize = 0; | |
537 | ep->e_vm.vm_tsize = 0; | |
538 | ep->e_vm.vm_dsize = 0; | |
539 | ep->e_vm.vm_ssize = 0; | |
540 | #ifndef sparc | |
541 | /* ep->e_vm.vm_pmap = XXX; */ | |
542 | #endif | |
543 | } else { | |
544 | register struct vmspace *vm = p->p_vmspace; | |
545 | ||
546 | ep->e_vm.vm_rssize = vm->vm_rssize; | |
547 | ep->e_vm.vm_tsize = vm->vm_tsize; | |
548 | ep->e_vm.vm_dsize = vm->vm_dsize; | |
549 | ep->e_vm.vm_ssize = vm->vm_ssize; | |
550 | #ifndef sparc | |
551 | ep->e_vm.vm_pmap = vm->vm_pmap; | |
552 | #endif | |
553 | } | |
31c481fa MK |
554 | if (p->p_pptr) |
555 | ep->e_ppid = p->p_pptr->p_pid; | |
556 | else | |
557 | ep->e_ppid = 0; | |
32041eb1 MK |
558 | ep->e_pgid = p->p_pgrp->pg_id; |
559 | ep->e_jobc = p->p_pgrp->pg_jobc; | |
560 | if ((p->p_flag&SCTTY) && | |
561 | (tp = ep->e_sess->s_ttyp)) { | |
562 | ep->e_tdev = tp->t_dev; | |
51d82109 | 563 | ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; |
32041eb1 MK |
564 | ep->e_tsess = tp->t_session; |
565 | } else | |
566 | ep->e_tdev = NODEV; | |
567 | ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; | |
568 | if (SESS_LEADER(p)) | |
569 | ep->e_flag |= EPROC_SLEADER; | |
570 | if (p->p_wmesg) | |
571 | strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); | |
572 | ep->e_xsize = ep->e_xrssize = 0; | |
573 | ep->e_xccount = ep->e_xswrss = 0; | |
574 | } | |
318784c4 | 575 | |
780d91b3 | 576 | #ifdef COMPAT_43 |
780d91b3 | 577 | #include <sys/socket.h> |
1fa29dab KM |
578 | #define KINFO_PROC (0<<8) |
579 | #define KINFO_RT (1<<8) | |
580 | #define KINFO_VNODE (2<<8) | |
581 | #define KINFO_FILE (3<<8) | |
582 | #define KINFO_METER (4<<8) | |
583 | #define KINFO_LOADAVG (5<<8) | |
584 | #define KINFO_CLOCKRATE (6<<8) | |
780d91b3 KM |
585 | |
586 | struct getkerninfo_args { | |
587 | int op; | |
588 | char *where; | |
589 | int *size; | |
590 | int arg; | |
591 | }; | |
592 | ||
593 | getkerninfo(p, uap, retval) | |
594 | struct proc *p; | |
595 | register struct getkerninfo_args *uap; | |
596 | int *retval; | |
318784c4 | 597 | { |
780d91b3 KM |
598 | int error, name[5]; |
599 | u_int size; | |
318784c4 | 600 | |
780d91b3 KM |
601 | if (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size))) |
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; | |
653 | return (copyout((caddr_t)&size, (caddr_t)uap->size, sizeof(size))); | |
318784c4 | 654 | } |
780d91b3 | 655 | #endif /* COMPAT_43 */ |