|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*-
27: * Copyright (c) 1982, 1986, 1989, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * This code is derived from software contributed to Berkeley by
31: * Mike Karels at Berkeley Software Design, Inc.
32: *
33: * Redistribution and use in source and binary forms, with or without
34: * modification, are permitted provided that the following conditions
35: * are met:
36: * 1. Redistributions of source code must retain the above copyright
37: * notice, this list of conditions and the following disclaimer.
38: * 2. Redistributions in binary form must reproduce the above copyright
39: * notice, this list of conditions and the following disclaimer in the
40: * documentation and/or other materials provided with the distribution.
41: * 3. All advertising materials mentioning features or use of this software
42: * must display the following acknowledgement:
43: * This product includes software developed by the University of
44: * California, Berkeley and its contributors.
45: * 4. Neither the name of the University nor the names of its contributors
46: * may be used to endorse or promote products derived from this software
47: * without specific prior written permission.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59: * SUCH DAMAGE.
60: *
61: * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
62: */
63:
64: /*
65: * sysctl system call.
66: */
67:
68: #include <sys/param.h>
69: #include <sys/systm.h>
70: #include <sys/kernel.h>
71: #include <sys/malloc.h>
72: #include <sys/proc.h>
73: #include <sys/file.h>
74: #include <sys/vnode.h>
75: #include <sys/unistd.h>
76: #include <sys/buf.h>
77: #include <sys/ioctl.h>
78: #include <sys/tty.h>
79: #include <sys/disklabel.h>
80: #include <sys/vm.h>
81: #include <sys/sysctl.h>
82:
83: #include <sys/mount.h>
84: #include <kdebug.h>
85: #if KDEBUG
86: #import <kern/kdebug.h>
87: #endif
88:
89: #ifdef __ppc__
90: #include <machdep/ppc/powermac.h>
91: #endif
92:
93: sysctlfn kern_sysctl;
94: sysctlfn hw_sysctl;
95: #ifdef DEBUG
96: sysctlfn debug_sysctl;
97: #endif
98: extern sysctlfn vm_sysctl;
99: extern sysctlfn vfs_sysctl;
100: extern sysctlfn net_sysctl;
101: extern sysctlfn cpu_sysctl;
102:
103: /*
104: * temporary location for vm_sysctl. This should be machine independant
105: */
106: vm_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
107: int *name;
108: u_int namelen;
109: void *oldp;
110: size_t *oldlenp;
111: void *newp;
112: size_t newlen;
113: struct proc *p;
114: {
115: int error, level, inthostid;
116: extern long avenrun[3], mach_factor[3];
117: struct loadavg loadinfo;
118:
119: //if (namelen != 1 && !(name[0] == VM_LOADAVG))
120: //return (ENOTDIR); /* overloaded */
121:
122: switch (name[0]) {
123: case VM_LOADAVG:
124: loadinfo.ldavg[0] = avenrun[0];
125: loadinfo.ldavg[1] = avenrun[1];
126: loadinfo.ldavg[2] = avenrun[2];
127: loadinfo.fscale = LSCALE;
128: return (sysctl_struct(oldp, oldlenp, newp, newlen, &loadinfo, sizeof(struct loadavg)));
129: case VM_MACHFACTOR:
130: loadinfo.ldavg[0] = mach_factor[0];
131: loadinfo.ldavg[1] = mach_factor[1];
132: loadinfo.ldavg[2] = mach_factor[2];
133: loadinfo.fscale = LSCALE;
134: return (sysctl_struct(oldp, oldlenp, newp, newlen, &loadinfo, sizeof(struct loadavg)));
135: case VM_METER:
136: return (EOPNOTSUPP);
137: case VM_MAXID:
138: return (EOPNOTSUPP);
139: default:
140: return (EOPNOTSUPP);
141: }
142: /* NOTREACHED */
143: return (EOPNOTSUPP);
144: }
145:
146: /*
147: * Locking and stats
148: */
149: static struct sysctl_lock {
150: int sl_lock;
151: int sl_want;
152: int sl_locked;
153: } memlock;
154:
155: struct __sysctl_args {
156: int *name;
157: u_int namelen;
158: void *old;
159: size_t *oldlenp;
160: void *new;
161: size_t newlen;
162: };
163: int
164: __sysctl(p, uap, retval)
165: struct proc *p;
166: register struct __sysctl_args *uap;
167: register_t *retval;
168: {
169: int error, dolock = 1;
170: size_t savelen, oldlen = 0;
171: sysctlfn *fn;
172: int name[CTL_MAXNAME];
173:
174: if (uap->new != NULL &&
175: (error = suser(p->p_ucred, &p->p_acflag)))
176: return (error);
177: /*
178: * all top-level sysctl names are non-terminal
179: */
180: if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
181: return (EINVAL);
182: if (error =
183: copyin(uap->name, &name, uap->namelen * sizeof(int)))
184: return (error);
185:
186: switch (name[0]) {
187: case CTL_KERN:
188: fn = kern_sysctl;
189: if (name[2] != KERN_VNODE) /* XXX */
190: dolock = 0;
191: break;
192: case CTL_HW:
193: fn = hw_sysctl;
194: break;
195: case CTL_VM:
196: fn = vm_sysctl;
197: break;
198: case CTL_NET:
199: fn = net_sysctl;
200: break;
201: case CTL_VFS:
202: fn = vfs_sysctl;
203: break;
204: case CTL_MACHDEP:
205: fn = cpu_sysctl;
206: break;
207: #ifdef DEBUG
208: case CTL_DEBUG:
209: fn = debug_sysctl;
210: break;
211: #endif
212: default:
213: return (EOPNOTSUPP);
214: }
215:
216: if (uap->oldlenp &&
217: (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen))))
218: return (error);
219: if (uap->old != NULL) {
220: if (!useracc(uap->old, oldlen, B_WRITE))
221: return (EFAULT);
222: while (memlock.sl_lock) {
223: memlock.sl_want = 1;
224: sleep((caddr_t)&memlock, PRIBIO+1);
225: memlock.sl_locked++;
226: }
227: memlock.sl_lock = 1;
228: if (dolock)
229: vslock(uap->old, oldlen);
230: savelen = oldlen;
231: }
232: error = (*fn)(name + 1, uap->namelen - 1, uap->old,
233: &oldlen, uap->new, uap->newlen, p);
234: if (uap->old != NULL) {
235: if (dolock)
236: vsunlock(uap->old, savelen, B_WRITE);
237: memlock.sl_lock = 0;
238: if (memlock.sl_want) {
239: memlock.sl_want = 0;
240: wakeup((caddr_t)&memlock);
241: }
242: }
243: if (error)
244: return (error);
245: if (uap->oldlenp)
246: error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen));
247: *retval = oldlen;
248: return (0);
249: }
250:
251: /*
252: * Attributes stored in the kernel.
253: */
254: extern char hostname[MAXHOSTNAMELEN]; /* defined in bsd/kern/init_main.c */
255: extern int hostnamelen;
256: extern char domainname[MAXHOSTNAMELEN];
257: extern int domainnamelen;
258: extern long hostid;
259: #ifdef INSECURE
260: int securelevel = -1;
261: #else
262: int securelevel;
263: #endif
264:
265: /*
266: * kernel related system variables.
267: */
268: kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
269: int *name;
270: u_int namelen;
271: void *oldp;
272: size_t *oldlenp;
273: void *newp;
274: size_t newlen;
275: struct proc *p;
276: {
277: int error, level, inthostid;
278: unsigned int oldval=0;
279: extern char ostype[], osrelease[], version[];
280:
281: /* all sysctl names at this level are terminal */
282: if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF
283: #if KDEBUG
284: || name[0] == KERN_KDEBUG
285: #endif
286: ))
287: return (ENOTDIR); /* overloaded */
288:
289: switch (name[0]) {
290: case KERN_OSTYPE:
291: return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
292: case KERN_OSRELEASE:
293: return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
294: case KERN_OSREV:
295: return (sysctl_rdint(oldp, oldlenp, newp, BSD));
296: case KERN_VERSION:
297: return (sysctl_rdstring(oldp, oldlenp, newp, version));
298: case KERN_MAXVNODES:
299: oldval = desiredvnodes;
300: error = sysctl_int(oldp, oldlenp, newp,
301: newlen, &desiredvnodes);
302: reset_vmobjectcache(oldval, desiredvnodes);
303: return(error);
304: case KERN_MAXPROC:
305: return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc));
306: case KERN_MAXFILES:
307: return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles));
308: case KERN_ARGMAX:
309: return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX));
310: case KERN_SECURELVL:
311: level = securelevel;
312: if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
313: newp == NULL)
314: return (error);
315: if (level < securelevel && p->p_pid != 1)
316: return (EPERM);
317: securelevel = level;
318: return (0);
319: case KERN_HOSTNAME:
320: error = sysctl_string(oldp, oldlenp, newp, newlen,
321: hostname, sizeof(hostname));
322: if (newp && !error)
323: hostnamelen = newlen;
324: return (error);
325: case KERN_DOMAINNAME:
326: error = sysctl_string(oldp, oldlenp, newp, newlen,
327: domainname, sizeof(domainname));
328: if (newp && !error)
329: domainnamelen = newlen;
330: return (error);
331: case KERN_HOSTID:
332: inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */
333: error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
334: hostid = inthostid;
335: return (error);
336: case KERN_CLOCKRATE:
337: return (sysctl_clockrate(oldp, oldlenp));
338: case KERN_BOOTTIME:
339: return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime,
340: sizeof(struct timeval)));
341: case KERN_VNODE:
342: return (sysctl_vnode(oldp, oldlenp));
343: case KERN_PROC:
344: return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
345: case KERN_FILE:
346: return (sysctl_file(oldp, oldlenp));
347: #ifdef GPROF
348: case KERN_PROF:
349: return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
350: newp, newlen));
351: #endif
352: case KERN_POSIX1:
353: return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION));
354: case KERN_NGROUPS:
355: return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX));
356: case KERN_JOB_CONTROL:
357: return (sysctl_rdint(oldp, oldlenp, newp, 1));
358: case KERN_SAVED_IDS:
359: #ifdef _POSIX_SAVED_IDS
360: return (sysctl_rdint(oldp, oldlenp, newp, 1));
361: #else
362: return (sysctl_rdint(oldp, oldlenp, newp, 0));
363: #endif
364: case KERN_MAXPARTITIONS:
365: return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS));
366: #if KDEBUG
367: case KERN_KDEBUG:
368: return (kdebug_ops(name + 1, namelen - 1, oldp, oldlenp));
369: #endif /* KDEBUG */
370: default:
371: return (EOPNOTSUPP);
372: }
373: /* NOTREACHED */
374: }
375:
376: /*
377: * hardware related system variables.
378: */
379: hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
380: int *name;
381: u_int namelen;
382: void *oldp;
383: size_t *oldlenp;
384: void *newp;
385: size_t newlen;
386: struct proc *p;
387: {
388: extern char machine[], cpu_model[];
389:
390: /* all sysctl names at this level are terminal */
391: if (namelen != 1)
392: return (ENOTDIR); /* overloaded */
393:
394: switch (name[0]) {
395: case HW_MACHINE:
396: return (sysctl_rdstring(oldp, oldlenp, newp, machine));
397: case HW_MODEL:
398: return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
399: case HW_NCPU:
400: return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */
401: case HW_BYTEORDER:
402: return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER));
403: case HW_PHYSMEM:
404: return (sysctl_rdint(oldp, oldlenp, newp, mem_size));
405: case HW_USERMEM:
406: return (sysctl_rdint(oldp, oldlenp, newp,
407: (mem_size - vm_page_wire_count * PAGE_SIZE)));
408: case HW_PAGESIZE:
409: return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE));
410: #ifdef __ppc__
411: case HW_NEWWORLD:
412: return (sysctl_rdint(oldp, oldlenp, newp, IsYosemite()));
413: #endif
414: default:
415: return (EOPNOTSUPP);
416: }
417: /* NOTREACHED */
418: }
419:
420: #ifdef DEBUG
421: /*
422: * Debugging related system variables.
423: */
424: #if DIAGNOSTIC
425: extern
426: #endif /* DIAGNOSTIC */
427: struct ctldebug debug0, debug1;
428: extern struct ctldebug debug2; /* dev/ppc/drvCuda needs var to debug ADB */
429: struct ctldebug debug3, debug4;
430: struct ctldebug debug5, debug6, debug7, debug8, debug9;
431: struct ctldebug debug10, debug11, debug12, debug13, debug14;
432: struct ctldebug debug15, debug16, debug17, debug18, debug19;
433: static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
434: &debug0, &debug1, &debug2, &debug3, &debug4,
435: &debug5, &debug6, &debug7, &debug8, &debug9,
436: &debug10, &debug11, &debug12, &debug13, &debug14,
437: &debug15, &debug16, &debug17, &debug18, &debug19,
438: };
439: int
440: debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
441: int *name;
442: u_int namelen;
443: void *oldp;
444: size_t *oldlenp;
445: void *newp;
446: size_t newlen;
447: struct proc *p;
448: {
449: struct ctldebug *cdp;
450:
451: /* all sysctl names at this level are name and field */
452: if (namelen != 2)
453: return (ENOTDIR); /* overloaded */
454: cdp = debugvars[name[0]];
455: if (cdp->debugname == 0)
456: return (EOPNOTSUPP);
457: switch (name[1]) {
458: case CTL_DEBUG_NAME:
459: return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
460: case CTL_DEBUG_VALUE:
461: return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
462: default:
463: return (EOPNOTSUPP);
464: }
465: /* NOTREACHED */
466: }
467: #endif /* DEBUG */
468:
469: /*
470: * Validate parameters and get old / set new parameters
471: * for an integer-valued sysctl function.
472: */
473: sysctl_int(oldp, oldlenp, newp, newlen, valp)
474: void *oldp;
475: size_t *oldlenp;
476: void *newp;
477: size_t newlen;
478: int *valp;
479: {
480: int error = 0;
481:
482: if (oldp && *oldlenp < sizeof(int))
483: return (ENOMEM);
484: if (newp && newlen != sizeof(int))
485: return (EINVAL);
486: *oldlenp = sizeof(int);
487: if (oldp)
488: error = copyout(valp, oldp, sizeof(int));
489: if (error == 0 && newp)
490: error = copyin(newp, valp, sizeof(int));
491: return (error);
492: }
493:
494: /*
495: * As above, but read-only.
496: */
497: sysctl_rdint(oldp, oldlenp, newp, val)
498: void *oldp;
499: size_t *oldlenp;
500: void *newp;
501: int val;
502: {
503: int error = 0;
504:
505: if (oldp && *oldlenp < sizeof(int))
506: return (ENOMEM);
507: if (newp)
508: return (EPERM);
509: *oldlenp = sizeof(int);
510: if (oldp)
511: error = copyout((caddr_t)&val, oldp, sizeof(int));
512: return (error);
513: }
514:
515: /*
516: * Validate parameters and get old / set new parameters
517: * for a string-valued sysctl function.
518: */
519: sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen)
520: void *oldp;
521: size_t *oldlenp;
522: void *newp;
523: size_t newlen;
524: char *str;
525: int maxlen;
526: {
527: int len, error = 0;
528:
529: len = strlen(str) + 1;
530: if (oldp && *oldlenp < len)
531: return (ENOMEM);
532: if (newp && newlen >= maxlen)
533: return (EINVAL);
534: if (oldp) {
535: *oldlenp = len;
536: error = copyout(str, oldp, len);
537: }
538: if (error == 0 && newp) {
539: error = copyin(newp, str, newlen);
540: str[newlen] = 0;
541: }
542: return (error);
543: }
544:
545: /*
546: * As above, but read-only.
547: */
548: sysctl_rdstring(oldp, oldlenp, newp, str)
549: void *oldp;
550: size_t *oldlenp;
551: void *newp;
552: char *str;
553: {
554: int len, error = 0;
555:
556: len = strlen(str) + 1;
557: if (oldp && *oldlenp < len)
558: return (ENOMEM);
559: if (newp)
560: return (EPERM);
561: *oldlenp = len;
562: if (oldp)
563: error = copyout(str, oldp, len);
564: return (error);
565: }
566:
567: /*
568: * Validate parameters and get old / set new parameters
569: * for a structure oriented sysctl function.
570: */
571: sysctl_struct(oldp, oldlenp, newp, newlen, sp, len)
572: void *oldp;
573: size_t *oldlenp;
574: void *newp;
575: size_t newlen;
576: void *sp;
577: int len;
578: {
579: int error = 0;
580:
581: if (oldp && *oldlenp < len)
582: return (ENOMEM);
583: if (newp && newlen > len)
584: return (EINVAL);
585: if (oldp) {
586: *oldlenp = len;
587: error = copyout(sp, oldp, len);
588: }
589: if (error == 0 && newp)
590: error = copyin(newp, sp, len);
591: return (error);
592: }
593:
594: /*
595: * Validate parameters and get old parameters
596: * for a structure oriented sysctl function.
597: */
598: sysctl_rdstruct(oldp, oldlenp, newp, sp, len)
599: void *oldp;
600: size_t *oldlenp;
601: void *newp, *sp;
602: int len;
603: {
604: int error = 0;
605:
606: if (oldp && *oldlenp < len)
607: return (ENOMEM);
608: if (newp)
609: return (EPERM);
610: *oldlenp = len;
611: if (oldp)
612: error = copyout(sp, oldp, len);
613: return (error);
614: }
615:
616: /*
617: * Get file structures.
618: */
619: sysctl_file(where, sizep)
620: char *where;
621: size_t *sizep;
622: {
623: int buflen, error;
624: struct file *fp;
625: char *start = where;
626:
627: buflen = *sizep;
628: if (where == NULL) {
629: /*
630: * overestimate by 10 files
631: */
632: *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
633: return (0);
634: }
635:
636: /*
637: * first copyout filehead
638: */
639: if (buflen < sizeof(filehead)) {
640: *sizep = 0;
641: return (0);
642: }
643: if (error = copyout((caddr_t)&filehead, where, sizeof(filehead)))
644: return (error);
645: buflen -= sizeof(filehead);
646: where += sizeof(filehead);
647:
648: /*
649: * followed by an array of file structures
650: */
651: for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
652: if (buflen < sizeof(struct file)) {
653: *sizep = where - start;
654: return (ENOMEM);
655: }
656: if (error = copyout((caddr_t)fp, where, sizeof (struct file)))
657: return (error);
658: buflen -= sizeof(struct file);
659: where += sizeof(struct file);
660: }
661: *sizep = where - start;
662: return (0);
663: }
664:
665: /*
666: * try over estimating by 5 procs
667: */
668: #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
669:
670: sysctl_doproc(name, namelen, where, sizep)
671: int *name;
672: u_int namelen;
673: char *where;
674: size_t *sizep;
675: {
676: register struct proc *p;
677: register struct kinfo_proc *dp = (struct kinfo_proc *)where;
678: register int needed = 0;
679: int buflen = where != NULL ? *sizep : 0;
680: int doingzomb;
681: struct kinfo_proc kproc;
682: int error = 0;
683:
684: if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
685: return (EINVAL);
686: p = allproc.lh_first;
687: doingzomb = 0;
688: again:
689: for (; p != 0; p = p->p_list.le_next) {
690: /*
691: * Skip embryonic processes.
692: */
693: if (p->p_stat == SIDL)
694: continue;
695: /*
696: * TODO - make more efficient (see notes below).
697: * do by session.
698: */
699: switch (name[0]) {
700:
701: case KERN_PROC_PID:
702: /* could do this with just a lookup */
703: if (p->p_pid != (pid_t)name[1])
704: continue;
705: break;
706:
707: case KERN_PROC_PGRP:
708: /* could do this by traversing pgrp */
709: if (p->p_pgrp->pg_id != (pid_t)name[1])
710: continue;
711: break;
712:
713: case KERN_PROC_TTY:
714: if ((p->p_flag & P_CONTROLT) == 0 ||
715: p->p_session->s_ttyp == NULL ||
716: p->p_session->s_ttyp->t_dev != (dev_t)name[1])
717: continue;
718: break;
719:
720: case KERN_PROC_UID:
721: if (p->p_ucred->cr_uid != (uid_t)name[1])
722: continue;
723: break;
724:
725: case KERN_PROC_RUID:
726: if (p->p_cred->p_ruid != (uid_t)name[1])
727: continue;
728: break;
729: }
730: if (buflen >= sizeof(struct kinfo_proc)) {
731: fill_proc(p, &kproc);
732: if (error = copyout((caddr_t)&kproc, &dp->kp_proc,
733: sizeof(struct kinfo_proc)))
734: return (error);
735: dp++;
736: buflen -= sizeof(struct kinfo_proc);
737: }
738: needed += sizeof(struct kinfo_proc);
739: }
740: if (doingzomb == 0) {
741: p = zombproc.lh_first;
742: doingzomb++;
743: goto again;
744: }
745: if (where != NULL) {
746: *sizep = (caddr_t)dp - where;
747: if (needed > *sizep)
748: return (ENOMEM);
749: } else {
750: needed += KERN_PROCSLOP;
751: *sizep = needed;
752: }
753: return (0);
754: }
755:
756: void
757: fill_proc(p,kp)
758: register struct proc *p;
759: register struct kinfo_proc *kp;
760: {
761: fill_externproc(p, &kp->kp_proc);
762: fill_eproc(p, &kp->kp_eproc);
763: }
764: /*
765: * Fill in an eproc structure for the specified process.
766: */
767: void
768: fill_eproc(p, ep)
769: register struct proc *p;
770: register struct eproc *ep;
771: {
772: register struct tty *tp;
773:
774: ep->e_paddr = p;
775: ep->e_sess = p->p_pgrp->pg_session;
776: ep->e_pcred = *p->p_cred;
777: ep->e_ucred = *p->p_ucred;
778: if (p->p_stat == SIDL || p->p_stat == SZOMB) {
779: ep->e_vm.vm_rssize = 0;
780: ep->e_vm.vm_tsize = 0;
781: ep->e_vm.vm_dsize = 0;
782: ep->e_vm.vm_ssize = 0;
783: /* ep->e_vm.vm_pmap = XXX; */
784: } else {
785: register vm_map_t vm = ((task_t)p->task)->map;
786:
787: ep->e_vm.vm_rssize = pmap_resident_count(vm->pmap); /*XXX*/
788: // ep->e_vm.vm_tsize = vm->vm_tsize;
789: // ep->e_vm.vm_dsize = vm->vm_dsize;
790: // ep->e_vm.vm_ssize = vm->vm_ssize;
791: }
792: if (p->p_pptr)
793: ep->e_ppid = p->p_pptr->p_pid;
794: else
795: ep->e_ppid = 0;
796: ep->e_pgid = p->p_pgrp->pg_id;
797: ep->e_jobc = p->p_pgrp->pg_jobc;
798: if ((p->p_flag & P_CONTROLT) &&
799: (tp = ep->e_sess->s_ttyp)) {
800: ep->e_tdev = tp->t_dev;
801: ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
802: ep->e_tsess = tp->t_session;
803: } else
804: ep->e_tdev = NODEV;
805: ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
806: if (SESS_LEADER(p))
807: ep->e_flag |= EPROC_SLEADER;
808: if (p->p_wmesg)
809: strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
810: ep->e_xsize = ep->e_xrssize = 0;
811: ep->e_xccount = ep->e_xswrss = 0;
812: }
813: /*
814: * Fill in an eproc structure for the specified process.
815: */
816: void
817: fill_externproc(p, exp)
818: register struct proc *p;
819: register struct extern_proc *exp;
820: {
821: exp->p_forw = exp->p_back = NULL;
822: exp->p_vmspace = NULL;
823: exp->p_sigacts = p->p_sigacts;
824: exp->p_flag = p->p_flag;
825: exp->p_stat = p->p_stat ;
826: exp->p_pid = p->p_pid ;
827: exp->p_oppid = p->p_oppid ;
828: exp->p_dupfd = p->p_dupfd ;
829: /* Mach related */
830: exp->user_stack = p->user_stack ;
831: exp->exit_thread = p->exit_thread ;
832: exp->p_debugger = p->p_debugger ;
833: exp->sigwait = p->sigwait ;
834: /* scheduling */
835: exp->p_estcpu = p->p_estcpu ;
836: exp->p_cpticks = p->p_cpticks ;
837: exp->p_pctcpu = p->p_pctcpu ;
838: exp->p_wchan = p->p_wchan ;
839: exp->p_wmesg = p->p_wmesg ;
840: exp->p_swtime = p->p_swtime ;
841: exp->p_slptime = p->p_slptime ;
842: bcopy(&p->p_realtimer, &exp->p_realtimer,sizeof(struct itimerval));
843: bcopy(&p->p_rtime, &exp->p_rtime,sizeof(struct timeval));
844: exp->p_uticks = p->p_uticks ;
845: exp->p_sticks = p->p_sticks ;
846: exp->p_iticks = p->p_iticks ;
847: exp->p_traceflag = p->p_traceflag ;
848: exp->p_tracep = p->p_tracep ;
849: exp->p_siglist = p->p_siglist ;
850: exp->p_textvp = p->p_textvp ;
851: exp->p_holdcnt = 0 ;
852: exp->p_sigmask = p->p_sigmask ;
853: exp->p_sigignore = p->p_sigignore ;
854: exp->p_sigcatch = p->p_sigcatch ;
855: exp->p_priority = p->p_priority ;
856: exp->p_usrpri = p->p_usrpri ;
857: exp->p_nice = p->p_nice ;
858: bcopy(&p->p_comm, &exp->p_comm,MAXCOMLEN);
859: exp->p_comm[MAXCOMLEN] = '\0';
860: exp->p_pgrp = p->p_pgrp ;
861: exp->p_addr = NULL;
862: exp->p_xstat = p->p_xstat ;
863: exp->p_acflag = p->p_acflag ;
864: exp->p_ru = p->p_ru ;
865: }
866:
867: #if KDEBUG
868: kdebug_ops(name, namelen, where, sizep)
869: int *name;
870: u_int namelen;
871: char *where;
872: size_t *sizep;
873: {
874: int size=*sizep;
875: int ret=0;
876: extern int kdbg_control(int *name, u_int namelen, char * where,size_t * sizep);
877:
878: switch(name[0]) {
879: case KERN_KDEFLAGS:
880: case KERN_KDDFLAGS:
881: case KERN_KDENABLE:
882: case KERN_KDSETBUF:
883: case KERN_KDGETBUF:
884: case KERN_KDSETUP:
885: case KERN_KDREMOVE:
886: case KERN_KDSETREG:
887: case KERN_KDGETREG:
888: case KERN_KDREADTR:
889: ret = kdbg_control(name, namelen, where, sizep);
890: break;
891: default:
892: ret= EOPNOTSUPP;
893: break;
894: }
895: return(ret);
896: }
897: #endif /* KDEBUG */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.