157843Smckusick /*- 257843Smckusick * Copyright (c) 1982, 1986, 1989, 1993 Regents of the University of California. 339963Smarc * All rights reserved. 439963Smarc * 557843Smckusick * This code is derived from software contributed to Berkeley by 657843Smckusick * Mike Karels at Berkeley Software Design, Inc. 757843Smckusick * 844435Sbostic * %sccs.include.redist.c% 939963Smarc * 10*58461Smckusick * @(#)kern_sysctl.c 7.30 (Berkeley) 03/04/93 1139963Smarc */ 1239963Smarc 1357843Smckusick /* 1457843Smckusick * sysctl system call. 1557843Smckusick */ 1657843Smckusick 1756517Sbostic #include <sys/param.h> 1857843Smckusick #include <sys/systm.h> 1957843Smckusick #include <sys/malloc.h> 2056517Sbostic #include <sys/proc.h> 2157843Smckusick #include <sys/file.h> 2257843Smckusick #include <sys/sysctl.h> 2357843Smckusick #include <sys/unistd.h> 2457843Smckusick #include <sys/buf.h> 2556517Sbostic #include <sys/ioctl.h> 2656517Sbostic #include <sys/tty.h> 2739963Smarc 2856517Sbostic #include <vm/vm.h> 2948407Skarels 3056517Sbostic #include <sys/kinfo_proc.h> 3148407Skarels 3257843Smckusick sysctlfn kern_sysctl; 3357843Smckusick sysctlfn hw_sysctl; 3457843Smckusick extern sysctlfn vm_sysctl; 3557843Smckusick extern sysctlfn fs_sysctl; 3657843Smckusick extern sysctlfn net_sysctl; 3757843Smckusick extern sysctlfn cpu_sysctl; 3840068Smarc 3957843Smckusick /* 4057843Smckusick * Locking and stats 4157843Smckusick */ 4257843Smckusick static struct sysctl_lock { 4357843Smckusick int sl_lock; 4457843Smckusick int sl_want; 4557843Smckusick int sl_locked; 4657843Smckusick } memlock; 4757843Smckusick 4857843Smckusick struct sysctl_args { 4957843Smckusick int *name; 5057843Smckusick u_int namelen; 5157843Smckusick void *old; 5257843Smckusick u_int *oldlenp; 5357843Smckusick void *new; 5457843Smckusick u_int newlen; 5554923Storek }; 5657843Smckusick 5757843Smckusick sysctl(p, uap, retval) 5843444Smckusick struct proc *p; 5957843Smckusick register struct sysctl_args *uap; 6043444Smckusick int *retval; 6143444Smckusick { 6257843Smckusick int error, dolock = 1; 6357843Smckusick u_int savelen, oldlen = 0; 6457843Smckusick sysctlfn *fn; 6557843Smckusick int name[CTL_MAXNAME]; 6639963Smarc 6757843Smckusick if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) 6857843Smckusick return (error); 6957843Smckusick /* 7057843Smckusick * all top-level sysctl names are non-terminal 7157843Smckusick */ 7257843Smckusick if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 7357843Smckusick return (EINVAL); 7457843Smckusick if (error = copyin(uap->name, &name, uap->namelen * sizeof(int))) 7557843Smckusick return (error); 7639963Smarc 7757843Smckusick switch (name[0]) { 7857843Smckusick case CTL_KERN: 7957843Smckusick fn = kern_sysctl; 8057843Smckusick if (name[2] != KERN_VNODE) /* XXX */ 8157843Smckusick dolock = 0; 8239963Smarc break; 8357843Smckusick case CTL_HW: 8457843Smckusick fn = hw_sysctl; 8540068Smarc break; 8657843Smckusick case CTL_VM: 8757843Smckusick fn = vm_sysctl; 8841181Smarc break; 8957843Smckusick case CTL_NET: 9057843Smckusick fn = net_sysctl; 9150149Smarc break; 9257843Smckusick #ifdef notyet 9357843Smckusick case CTL_FS: 9457843Smckusick fn = fs_sysctl; 9550909Smckusick break; 9657843Smckusick case CTL_DEBUG: 9757843Smckusick fn = debug_sysctl; 9852669Smckusick break; 9957843Smckusick case CTL_MACHDEP: 10057843Smckusick fn = cpu_sysctl; 10152669Smckusick break; 10257843Smckusick #endif 10339963Smarc default: 10457843Smckusick return (EOPNOTSUPP); 10539963Smarc } 10657843Smckusick 10757843Smckusick if (uap->oldlenp && 10857843Smckusick (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen)))) 10957843Smckusick return (error); 11057843Smckusick if (uap->old != NULL) { 11157843Smckusick if (!useracc(uap->old, oldlen, B_WRITE)) 11257843Smckusick return (EFAULT); 11357843Smckusick while (memlock.sl_lock) { 11457843Smckusick memlock.sl_want = 1; 11557843Smckusick sleep((caddr_t)&memlock, PRIBIO+1); 11657843Smckusick memlock.sl_locked++; 11757843Smckusick } 11857843Smckusick memlock.sl_lock = 1; 11957843Smckusick if (dolock) 12057843Smckusick vslock(uap->old, oldlen); 12157843Smckusick savelen = oldlen; 12240813Smarc } 12357843Smckusick error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen, 12458415Smckusick uap->new, uap->newlen, p); 12557843Smckusick if (uap->old != NULL) { 12657843Smckusick if (dolock) 12757843Smckusick vsunlock(uap->old, savelen, B_WRITE); 12857843Smckusick memlock.sl_lock = 0; 12957843Smckusick if (memlock.sl_want) { 13057843Smckusick memlock.sl_want = 0; 13157843Smckusick wakeup((caddr_t)&memlock); 13257843Smckusick } 13340206Smarc } 13457843Smckusick if (error) 13557843Smckusick return (error); 13657843Smckusick if (uap->oldlenp) 13757843Smckusick error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen)); 13857843Smckusick *retval = oldlen; 13957843Smckusick return (0); 14057843Smckusick } 14140206Smarc 14257843Smckusick /* 14357843Smckusick * Attributes stored in the kernel. 14457843Smckusick */ 14557843Smckusick char hostname[MAXHOSTNAMELEN]; 14657843Smckusick int hostnamelen; 14757843Smckusick long hostid; 14858415Smckusick int securelevel; 14957843Smckusick 15058415Smckusick /* 15158415Smckusick * kernel related system variables. 15258415Smckusick */ 15358415Smckusick kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 15457843Smckusick int *name; 15557843Smckusick u_int namelen; 15657843Smckusick void *oldp; 15757843Smckusick u_int *oldlenp; 15857843Smckusick void *newp; 15957843Smckusick u_int newlen; 16058415Smckusick struct proc *p; 16157843Smckusick { 16258415Smckusick int error, level; 16357843Smckusick extern char ostype[], osrelease[], version[]; 16457843Smckusick 16557843Smckusick /* all sysctl names at this level are terminal */ 16657843Smckusick if (namelen != 1 && name[0] != KERN_PROC) 16757843Smckusick return (ENOTDIR); /* overloaded */ 16857843Smckusick 16957843Smckusick switch (name[0]) { 17057843Smckusick case KERN_OSTYPE: 17157843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 17257843Smckusick case KERN_OSRELEASE: 17357843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 17457843Smckusick case KERN_OSREV: 17557843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, BSD)); 17657843Smckusick case KERN_VERSION: 17757843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, version)); 17857843Smckusick case KERN_POSIX1: 17957843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 18057843Smckusick case KERN_MAXPROC: 18157843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); 18257843Smckusick case KERN_MAXFILES: 18357843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 18457843Smckusick case KERN_ARGMAX: 18557843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 18657843Smckusick case KERN_HOSTNAME: 18757843Smckusick error = sysctl_string(oldp, oldlenp, newp, newlen, 18857843Smckusick hostname, sizeof(hostname)); 18957843Smckusick if (!error) 19057843Smckusick hostnamelen = newlen; 19157843Smckusick return (error); 19257843Smckusick case KERN_HOSTID: 19357843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &hostid)); 19458415Smckusick case KERN_SECURELVL: 19558415Smckusick level = securelevel; 19658415Smckusick if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 19758415Smckusick newp == NULL) 19858415Smckusick return (error); 19958415Smckusick if (level < securelevel && p->p_pid != 1) 20058415Smckusick return (EPERM); 20158415Smckusick securelevel = level; 20258415Smckusick return (0); 20357843Smckusick case KERN_CLOCKRATE: 20457843Smckusick return (sysctl_clockrate(oldp, oldlenp)); 20557843Smckusick case KERN_FILE: 20657843Smckusick return (sysctl_file(oldp, oldlenp)); 20757843Smckusick case KERN_VNODE: 20857843Smckusick return (sysctl_vnode(oldp, oldlenp)); 20957843Smckusick case KERN_PROC: 21057843Smckusick return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); 21157843Smckusick default: 21257843Smckusick return (EOPNOTSUPP); 21352405Storek } 21457843Smckusick /* NOTREACHED */ 21557843Smckusick } 21657843Smckusick 21758415Smckusick /* 21858415Smckusick * hardware related system variables. 21958415Smckusick */ 22058415Smckusick hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 22157843Smckusick int *name; 22257843Smckusick u_int namelen; 22357843Smckusick void *oldp; 22457843Smckusick u_int *oldlenp; 22557843Smckusick void *newp; 22657843Smckusick u_int newlen; 22758415Smckusick struct proc *p; 22857843Smckusick { 22957843Smckusick extern char machine[], cpu_model[]; 23057843Smckusick 23157843Smckusick /* all sysctl names at this level are terminal */ 23257843Smckusick if (namelen != 1) 23357843Smckusick return (ENOTDIR); /* overloaded */ 23457843Smckusick 23557843Smckusick switch (name[0]) { 23657843Smckusick case HW_MACHINE: 23757843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 23857843Smckusick case HW_MODEL: 23957843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 24057843Smckusick case HW_NCPU: 24157843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ 24257843Smckusick case HW_CPUSPEED: 24357843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); 24457843Smckusick case HW_PHYSMEM: 24557843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 24657843Smckusick case HW_USERMEM: 24757843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, 24857843Smckusick ctob(physmem - cnt.v_wire_count))); 24957843Smckusick case HW_PAGESIZE: 25057843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 25157843Smckusick default: 25257843Smckusick return (EOPNOTSUPP); 25357843Smckusick } 25457843Smckusick /* NOTREACHED */ 25557843Smckusick } 25657843Smckusick 25757843Smckusick /* 25857843Smckusick * Validate parameters and get old / set new parameters 25957843Smckusick * for an integer-valued sysctl function. 26057843Smckusick */ 26157843Smckusick sysctl_int(oldp, oldlenp, newp, newlen, valp) 26257843Smckusick void *oldp; 26357843Smckusick u_int *oldlenp; 26457843Smckusick void *newp; 26557843Smckusick u_int newlen; 26657843Smckusick int *valp; 26757843Smckusick { 26857843Smckusick int error = 0; 26957843Smckusick 27057843Smckusick if (oldp && *oldlenp < sizeof(int)) 27157843Smckusick return (ENOMEM); 27257843Smckusick if (newp && newlen != sizeof(int)) 27357843Smckusick return (EINVAL); 27457843Smckusick *oldlenp = sizeof(int); 27557843Smckusick if (oldp) 27657843Smckusick error = copyout(valp, oldp, sizeof(int)); 27757843Smckusick if (error == 0 && newp) 27857843Smckusick error = copyin(newp, valp, sizeof(int)); 27943444Smckusick return (error); 28039963Smarc } 28139963Smarc 28257843Smckusick /* 28357843Smckusick * As above, but read-only. 28457843Smckusick */ 28557843Smckusick sysctl_rdint(oldp, oldlenp, newp, val) 28657843Smckusick void *oldp; 28757843Smckusick u_int *oldlenp; 28857843Smckusick void *newp; 28957843Smckusick int val; 29057843Smckusick { 29157843Smckusick int error = 0; 29257843Smckusick 29357843Smckusick if (oldp && *oldlenp < sizeof(int)) 29457843Smckusick return (ENOMEM); 29557843Smckusick if (newp) 29657843Smckusick return (EPERM); 29757843Smckusick *oldlenp = sizeof(int); 29857843Smckusick if (oldp) 29957843Smckusick error = copyout((caddr_t)&val, oldp, sizeof(int)); 30057843Smckusick return (error); 30157843Smckusick } 30257843Smckusick 30357843Smckusick /* 30457843Smckusick * Validate parameters and get old / set new parameters 30557843Smckusick * for a string-valued sysctl function. 30657843Smckusick */ 30757843Smckusick sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) 30857843Smckusick void *oldp; 30957843Smckusick u_int *oldlenp; 31057843Smckusick void *newp; 31157843Smckusick u_int newlen; 31257843Smckusick char *str; 31357843Smckusick int maxlen; 31457843Smckusick { 31557843Smckusick int len, error = 0; 31657843Smckusick 31757843Smckusick len = strlen(str) + 1; 31857843Smckusick if (oldp && *oldlenp < len) 31957843Smckusick return (ENOMEM); 32057843Smckusick if (newp && newlen >= maxlen) 32157843Smckusick return (EINVAL); 32258128Sralph if (oldp) { 32358128Sralph *oldlenp = len; 32457843Smckusick error = copyout(str, oldp, len); 32558128Sralph } 32657843Smckusick if (error == 0 && newp) { 32757843Smckusick error = copyin(newp, str, newlen); 32857843Smckusick str[newlen] = 0; 32957843Smckusick } 33057843Smckusick return (error); 33157843Smckusick } 33257843Smckusick 33357843Smckusick /* 33457843Smckusick * As above, but read-only. 33557843Smckusick */ 33657843Smckusick sysctl_rdstring(oldp, oldlenp, newp, str) 33757843Smckusick void *oldp; 33857843Smckusick u_int *oldlenp; 33957843Smckusick void *newp; 34057843Smckusick char *str; 34157843Smckusick { 34257843Smckusick int len, error = 0; 34357843Smckusick 34457843Smckusick len = strlen(str) + 1; 34557843Smckusick if (oldp && *oldlenp < len) 34657843Smckusick return (ENOMEM); 34757843Smckusick if (newp) 34857843Smckusick return (EPERM); 34957843Smckusick *oldlenp = len; 35057843Smckusick if (oldp) 35157843Smckusick error = copyout(str, oldp, len); 35257843Smckusick return (error); 35357843Smckusick } 35457843Smckusick 35557843Smckusick /* 35657843Smckusick * Validate parameters and get old parameters 35757843Smckusick * for a structure oriented sysctl function. 35857843Smckusick */ 35957843Smckusick sysctl_rdstruct(oldp, oldlenp, newp, sp, len) 36057843Smckusick void *oldp; 36157843Smckusick u_int *oldlenp; 36257843Smckusick void *newp; 36357843Smckusick void *sp; 36457843Smckusick int len; 36557843Smckusick { 36657843Smckusick int error = 0; 36757843Smckusick 36857843Smckusick if (oldp && *oldlenp < len) 36957843Smckusick return (ENOMEM); 37057843Smckusick if (newp) 37157843Smckusick return (EPERM); 37257843Smckusick *oldlenp = len; 37357843Smckusick if (oldp) 37457843Smckusick error = copyout(sp, oldp, len); 37557843Smckusick return (error); 37657843Smckusick } 37757843Smckusick 37857843Smckusick /* 37957843Smckusick * Get file structures. 38057843Smckusick */ 38157843Smckusick sysctl_file(where, sizep) 38257843Smckusick char *where; 38357843Smckusick int *sizep; 38457843Smckusick { 38557843Smckusick int buflen, error; 38657843Smckusick struct file *fp; 38757843Smckusick char *start = where; 38857843Smckusick 38957843Smckusick buflen = *sizep; 39057843Smckusick if (where == NULL) { 39157843Smckusick /* 39257843Smckusick * overestimate by 10 files 39357843Smckusick */ 39457843Smckusick *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 39557843Smckusick return (0); 39657843Smckusick } 39757843Smckusick 39857843Smckusick /* 39957843Smckusick * first copyout filehead 40057843Smckusick */ 40157843Smckusick if (buflen < sizeof(filehead)) { 40257843Smckusick *sizep = 0; 40357843Smckusick return (0); 40457843Smckusick } 40557843Smckusick if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) 40657843Smckusick return (error); 40757843Smckusick buflen += sizeof(filehead); 40857843Smckusick where += sizeof(filehead); 40957843Smckusick 41057843Smckusick /* 41157843Smckusick * followed by an array of file structures 41257843Smckusick */ 41357843Smckusick for (fp = filehead; fp != NULL; fp = fp->f_filef) { 41457843Smckusick if (buflen < sizeof(struct file)) { 41557843Smckusick *sizep = where - start; 41657843Smckusick return (ENOMEM); 41757843Smckusick } 41857843Smckusick if (error = copyout((caddr_t)fp, where, sizeof (struct file))) 41957843Smckusick return (error); 42057843Smckusick buflen -= sizeof(struct file); 42157843Smckusick where += sizeof(struct file); 42257843Smckusick } 42357843Smckusick *sizep = where - start; 42457843Smckusick return (0); 42557843Smckusick } 42657843Smckusick 42739963Smarc /* 42839963Smarc * try over estimating by 5 procs 42939963Smarc */ 43057843Smckusick #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 43139963Smarc 43257843Smckusick sysctl_doproc(name, namelen, where, sizep) 43357843Smckusick int *name; 43457843Smckusick int namelen; 43539963Smarc char *where; 43657843Smckusick int *sizep; 43739963Smarc { 43839963Smarc register struct proc *p; 43943419Smarc register struct kinfo_proc *dp = (struct kinfo_proc *)where; 44057843Smckusick register int needed = 0; 44157843Smckusick int buflen = where != NULL ? *sizep : 0; 44239963Smarc int doingzomb; 44340067Smarc struct eproc eproc; 44439963Smarc int error = 0; 44539963Smarc 44657843Smckusick if (namelen != 2) 44757843Smckusick return (EINVAL); 44854755Storek p = (struct proc *)allproc; 44939963Smarc doingzomb = 0; 45039963Smarc again: 45139963Smarc for (; p != NULL; p = p->p_nxt) { 45253819Smckusick /* 45353819Smckusick * Skip embryonic processes. 45453819Smckusick */ 45553819Smckusick if (p->p_stat == SIDL) 45653819Smckusick continue; 45739963Smarc /* 45839963Smarc * TODO - make more efficient (see notes below). 45939963Smarc * do by session. 46039963Smarc */ 46157843Smckusick switch (name[0]) { 46239963Smarc 46357843Smckusick case KERN_PROC_PID: 46439963Smarc /* could do this with just a lookup */ 46557843Smckusick if (p->p_pid != (pid_t)name[1]) 46639963Smarc continue; 46739963Smarc break; 46839963Smarc 46957843Smckusick case KERN_PROC_PGRP: 47039963Smarc /* could do this by traversing pgrp */ 47157843Smckusick if (p->p_pgrp->pg_id != (pid_t)name[1]) 47239963Smarc continue; 47339963Smarc break; 47439963Smarc 47557843Smckusick case KERN_PROC_TTY: 47639963Smarc if ((p->p_flag&SCTTY) == 0 || 47739963Smarc p->p_session->s_ttyp == NULL || 47857843Smckusick p->p_session->s_ttyp->t_dev != (dev_t)name[1]) 47939963Smarc continue; 48039963Smarc break; 48139963Smarc 48257843Smckusick case KERN_PROC_UID: 48357843Smckusick if (p->p_ucred->cr_uid != (uid_t)name[1]) 48439963Smarc continue; 48539963Smarc break; 48639963Smarc 48757843Smckusick case KERN_PROC_RUID: 48857843Smckusick if (p->p_cred->p_ruid != (uid_t)name[1]) 48939963Smarc continue; 49039963Smarc break; 49139963Smarc } 49257843Smckusick if (buflen >= sizeof(struct kinfo_proc)) { 49348407Skarels fill_eproc(p, &eproc); 49443419Smarc if (error = copyout((caddr_t)p, &dp->kp_proc, 49557843Smckusick sizeof(struct proc))) 49639963Smarc return (error); 49743419Smarc if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, 49857843Smckusick sizeof(eproc))) 49939963Smarc return (error); 50043419Smarc dp++; 50157843Smckusick buflen -= sizeof(struct kinfo_proc); 50239963Smarc } 50357843Smckusick needed += sizeof(struct kinfo_proc); 50439963Smarc } 50539963Smarc if (doingzomb == 0) { 50639963Smarc p = zombproc; 50739963Smarc doingzomb++; 50839963Smarc goto again; 50939963Smarc } 51057843Smckusick if (where != NULL) { 51157843Smckusick *sizep = (caddr_t)dp - where; 51257843Smckusick if (needed > *sizep) 51357843Smckusick return (ENOMEM); 51457843Smckusick } else { 51557843Smckusick needed += KERN_PROCSLOP; 51657843Smckusick *sizep = needed; 51757843Smckusick } 51839963Smarc return (0); 51939963Smarc } 52048407Skarels 52148407Skarels /* 52248407Skarels * Fill in an eproc structure for the specified process. 52348407Skarels */ 52448407Skarels void 52548407Skarels fill_eproc(p, ep) 52648407Skarels register struct proc *p; 52748407Skarels register struct eproc *ep; 52848407Skarels { 52948407Skarels register struct tty *tp; 53048407Skarels 53148407Skarels ep->e_paddr = p; 53248407Skarels ep->e_sess = p->p_pgrp->pg_session; 53348407Skarels ep->e_pcred = *p->p_cred; 53448407Skarels ep->e_ucred = *p->p_ucred; 53552405Storek if (p->p_stat == SIDL || p->p_stat == SZOMB) { 53652405Storek ep->e_vm.vm_rssize = 0; 53752405Storek ep->e_vm.vm_tsize = 0; 53852405Storek ep->e_vm.vm_dsize = 0; 53952405Storek ep->e_vm.vm_ssize = 0; 54052405Storek #ifndef sparc 54152405Storek /* ep->e_vm.vm_pmap = XXX; */ 54252405Storek #endif 54352405Storek } else { 54452405Storek register struct vmspace *vm = p->p_vmspace; 54552405Storek 54652405Storek ep->e_vm.vm_rssize = vm->vm_rssize; 54752405Storek ep->e_vm.vm_tsize = vm->vm_tsize; 54852405Storek ep->e_vm.vm_dsize = vm->vm_dsize; 54952405Storek ep->e_vm.vm_ssize = vm->vm_ssize; 55052405Storek #ifndef sparc 55152405Storek ep->e_vm.vm_pmap = vm->vm_pmap; 55252405Storek #endif 55352405Storek } 55449141Skarels if (p->p_pptr) 55549141Skarels ep->e_ppid = p->p_pptr->p_pid; 55649141Skarels else 55749141Skarels ep->e_ppid = 0; 55848407Skarels ep->e_pgid = p->p_pgrp->pg_id; 55948407Skarels ep->e_jobc = p->p_pgrp->pg_jobc; 56048407Skarels if ((p->p_flag&SCTTY) && 56148407Skarels (tp = ep->e_sess->s_ttyp)) { 56248407Skarels ep->e_tdev = tp->t_dev; 56350022Skarels ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 56448407Skarels ep->e_tsess = tp->t_session; 56548407Skarels } else 56648407Skarels ep->e_tdev = NODEV; 56748407Skarels ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 56848407Skarels if (SESS_LEADER(p)) 56948407Skarels ep->e_flag |= EPROC_SLEADER; 57048407Skarels if (p->p_wmesg) 57148407Skarels strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 57248407Skarels ep->e_xsize = ep->e_xrssize = 0; 57348407Skarels ep->e_xccount = ep->e_xswrss = 0; 57448407Skarels } 57550149Smarc 57657843Smckusick #ifdef COMPAT_43 57757843Smckusick #include <sys/socket.h> 57857906Smckusick #define KINFO_PROC (0<<8) 57957906Smckusick #define KINFO_RT (1<<8) 58057906Smckusick #define KINFO_VNODE (2<<8) 58157906Smckusick #define KINFO_FILE (3<<8) 58257906Smckusick #define KINFO_METER (4<<8) 58357906Smckusick #define KINFO_LOADAVG (5<<8) 58457906Smckusick #define KINFO_CLOCKRATE (6<<8) 58557843Smckusick 58657843Smckusick struct getkerninfo_args { 58757843Smckusick int op; 58857843Smckusick char *where; 58957843Smckusick int *size; 59057843Smckusick int arg; 59157843Smckusick }; 59257843Smckusick 59357843Smckusick getkerninfo(p, uap, retval) 59457843Smckusick struct proc *p; 59557843Smckusick register struct getkerninfo_args *uap; 59657843Smckusick int *retval; 59750149Smarc { 59857843Smckusick int error, name[5]; 59957843Smckusick u_int size; 60050149Smarc 601*58461Smckusick if (uap->size && 602*58461Smckusick error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size))) 60357843Smckusick return (error); 60450149Smarc 60557906Smckusick switch (uap->op & 0xff00) { 60650149Smarc 60757843Smckusick case KINFO_RT: 60857843Smckusick name[0] = PF_ROUTE; 60957843Smckusick name[1] = 0; 61057843Smckusick name[2] = (uap->op & 0xff0000) >> 16; 61157843Smckusick name[3] = uap->op & 0xff; 61257843Smckusick name[4] = uap->arg; 61358415Smckusick error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p); 61457843Smckusick break; 61557843Smckusick 61657843Smckusick case KINFO_VNODE: 61757843Smckusick name[0] = KERN_VNODE; 61858415Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 61957843Smckusick break; 62057843Smckusick 62157843Smckusick case KINFO_PROC: 62257843Smckusick name[0] = KERN_PROC; 62357843Smckusick name[1] = uap->op & 0xff; 62457843Smckusick name[2] = uap->arg; 62558415Smckusick error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p); 62657843Smckusick break; 62757843Smckusick 62857843Smckusick case KINFO_FILE: 62957843Smckusick name[0] = KERN_FILE; 63058415Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 63157843Smckusick break; 63257843Smckusick 63357843Smckusick case KINFO_METER: 63457843Smckusick name[0] = VM_METER; 63558415Smckusick error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); 63657843Smckusick break; 63757843Smckusick 63857843Smckusick case KINFO_LOADAVG: 63957843Smckusick name[0] = VM_LOADAVG; 64058415Smckusick error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); 64157843Smckusick break; 64257843Smckusick 64357843Smckusick case KINFO_CLOCKRATE: 64457843Smckusick name[0] = KERN_CLOCKRATE; 64558415Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 64657843Smckusick break; 64757843Smckusick 64857843Smckusick default: 64958415Smckusick return (EOPNOTSUPP); 65050149Smarc } 65157843Smckusick if (error) 65257843Smckusick return (error); 65357843Smckusick *retval = size; 654*58461Smckusick if (uap->size) 655*58461Smckusick error = copyout((caddr_t)&size, (caddr_t)uap->size, 656*58461Smckusick sizeof(size)); 657*58461Smckusick return (error); 65850149Smarc } 65957843Smckusick #endif /* COMPAT_43 */ 660