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