1*57843Smckusick /*- 2*57843Smckusick * Copyright (c) 1982, 1986, 1989, 1993 Regents of the University of California. 339963Smarc * All rights reserved. 439963Smarc * 5*57843Smckusick * This code is derived from software contributed to Berkeley by 6*57843Smckusick * Mike Karels at Berkeley Software Design, Inc. 7*57843Smckusick * 844435Sbostic * %sccs.include.redist.c% 939963Smarc * 10*57843Smckusick * @(#)kern_sysctl.c 7.26 (Berkeley) 02/04/93 1139963Smarc */ 1239963Smarc 13*57843Smckusick /* 14*57843Smckusick * sysctl system call. 15*57843Smckusick */ 16*57843Smckusick 1756517Sbostic #include <sys/param.h> 18*57843Smckusick #include <sys/systm.h> 19*57843Smckusick #include <sys/malloc.h> 2056517Sbostic #include <sys/proc.h> 21*57843Smckusick #include <sys/file.h> 22*57843Smckusick #include <sys/sysctl.h> 23*57843Smckusick #include <sys/unistd.h> 24*57843Smckusick #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 32*57843Smckusick sysctlfn kern_sysctl; 33*57843Smckusick sysctlfn hw_sysctl; 34*57843Smckusick extern sysctlfn vm_sysctl; 35*57843Smckusick extern sysctlfn fs_sysctl; 36*57843Smckusick extern sysctlfn net_sysctl; 37*57843Smckusick extern sysctlfn cpu_sysctl; 3840068Smarc 39*57843Smckusick /* 40*57843Smckusick * Locking and stats 41*57843Smckusick */ 42*57843Smckusick static struct sysctl_lock { 43*57843Smckusick int sl_lock; 44*57843Smckusick int sl_want; 45*57843Smckusick int sl_locked; 46*57843Smckusick } memlock; 47*57843Smckusick 48*57843Smckusick struct sysctl_args { 49*57843Smckusick int *name; 50*57843Smckusick u_int namelen; 51*57843Smckusick void *old; 52*57843Smckusick u_int *oldlenp; 53*57843Smckusick void *new; 54*57843Smckusick u_int newlen; 5554923Storek }; 56*57843Smckusick 57*57843Smckusick #define STK_PARAMS 32 /* largest old/new values on stack */ 58*57843Smckusick 59*57843Smckusick sysctl(p, uap, retval) 6043444Smckusick struct proc *p; 61*57843Smckusick register struct sysctl_args *uap; 6243444Smckusick int *retval; 6343444Smckusick { 64*57843Smckusick int error, dolock = 1; 65*57843Smckusick u_int savelen, oldlen = 0; 66*57843Smckusick sysctlfn *fn; 67*57843Smckusick int name[CTL_MAXNAME]; 6839963Smarc 69*57843Smckusick if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) 70*57843Smckusick return (error); 71*57843Smckusick /* 72*57843Smckusick * all top-level sysctl names are non-terminal 73*57843Smckusick */ 74*57843Smckusick if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 75*57843Smckusick return (EINVAL); 76*57843Smckusick if (error = copyin(uap->name, &name, uap->namelen * sizeof(int))) 77*57843Smckusick return (error); 7839963Smarc 79*57843Smckusick switch (name[0]) { 80*57843Smckusick case CTL_KERN: 81*57843Smckusick fn = kern_sysctl; 82*57843Smckusick if (name[2] != KERN_VNODE) /* XXX */ 83*57843Smckusick dolock = 0; 8439963Smarc break; 85*57843Smckusick case CTL_HW: 86*57843Smckusick fn = hw_sysctl; 8740068Smarc break; 88*57843Smckusick case CTL_VM: 89*57843Smckusick fn = vm_sysctl; 9041181Smarc break; 91*57843Smckusick case CTL_NET: 92*57843Smckusick fn = net_sysctl; 9350149Smarc break; 94*57843Smckusick #ifdef notyet 95*57843Smckusick case CTL_FS: 96*57843Smckusick fn = fs_sysctl; 9750909Smckusick break; 98*57843Smckusick case CTL_DEBUG: 99*57843Smckusick fn = debug_sysctl; 10052669Smckusick break; 101*57843Smckusick case CTL_MACHDEP: 102*57843Smckusick fn = cpu_sysctl; 10352669Smckusick break; 104*57843Smckusick #endif 10539963Smarc default: 106*57843Smckusick return (EOPNOTSUPP); 10739963Smarc } 108*57843Smckusick 109*57843Smckusick if (uap->oldlenp && 110*57843Smckusick (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen)))) 111*57843Smckusick return (error); 112*57843Smckusick if (uap->old != NULL) { 113*57843Smckusick if (!useracc(uap->old, oldlen, B_WRITE)) 114*57843Smckusick return (EFAULT); 115*57843Smckusick while (memlock.sl_lock) { 116*57843Smckusick memlock.sl_want = 1; 117*57843Smckusick sleep((caddr_t)&memlock, PRIBIO+1); 118*57843Smckusick memlock.sl_locked++; 119*57843Smckusick } 120*57843Smckusick memlock.sl_lock = 1; 121*57843Smckusick if (dolock) 122*57843Smckusick vslock(uap->old, oldlen); 123*57843Smckusick savelen = oldlen; 12440813Smarc } 125*57843Smckusick error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen, 126*57843Smckusick uap->new, uap->newlen); 127*57843Smckusick if (uap->old != NULL) { 128*57843Smckusick if (dolock) 129*57843Smckusick vsunlock(uap->old, savelen, B_WRITE); 130*57843Smckusick memlock.sl_lock = 0; 131*57843Smckusick if (memlock.sl_want) { 132*57843Smckusick memlock.sl_want = 0; 133*57843Smckusick wakeup((caddr_t)&memlock); 134*57843Smckusick } 13540206Smarc } 136*57843Smckusick if (error) 137*57843Smckusick return (error); 138*57843Smckusick if (uap->oldlenp) 139*57843Smckusick error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen)); 140*57843Smckusick *retval = oldlen; 141*57843Smckusick return (0); 142*57843Smckusick } 14340206Smarc 144*57843Smckusick /* 145*57843Smckusick * Attributes stored in the kernel. 146*57843Smckusick */ 147*57843Smckusick char hostname[MAXHOSTNAMELEN]; 148*57843Smckusick int hostnamelen; 149*57843Smckusick long hostid; 150*57843Smckusick 151*57843Smckusick kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 152*57843Smckusick int *name; 153*57843Smckusick u_int namelen; 154*57843Smckusick void *oldp; 155*57843Smckusick u_int *oldlenp; 156*57843Smckusick void *newp; 157*57843Smckusick u_int newlen; 158*57843Smckusick { 159*57843Smckusick int error; 160*57843Smckusick extern char ostype[], osrelease[], version[]; 161*57843Smckusick 162*57843Smckusick /* all sysctl names at this level are terminal */ 163*57843Smckusick if (namelen != 1 && name[0] != KERN_PROC) 164*57843Smckusick return (ENOTDIR); /* overloaded */ 165*57843Smckusick 166*57843Smckusick switch (name[0]) { 167*57843Smckusick case KERN_OSTYPE: 168*57843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 169*57843Smckusick case KERN_OSRELEASE: 170*57843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 171*57843Smckusick case KERN_OSREV: 172*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, BSD)); 173*57843Smckusick case KERN_VERSION: 174*57843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, version)); 175*57843Smckusick case KERN_POSIX1: 176*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 177*57843Smckusick case KERN_MAXPROC: 178*57843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); 179*57843Smckusick case KERN_MAXFILES: 180*57843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 181*57843Smckusick case KERN_ARGMAX: 182*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 183*57843Smckusick case KERN_HOSTNAME: 184*57843Smckusick error = sysctl_string(oldp, oldlenp, newp, newlen, 185*57843Smckusick hostname, sizeof(hostname)); 186*57843Smckusick if (!error) 187*57843Smckusick hostnamelen = newlen; 188*57843Smckusick return (error); 189*57843Smckusick case KERN_HOSTID: 190*57843Smckusick return (sysctl_int(oldp, oldlenp, newp, newlen, &hostid)); 191*57843Smckusick case KERN_CLOCKRATE: 192*57843Smckusick return (sysctl_clockrate(oldp, oldlenp)); 193*57843Smckusick case KERN_FILE: 194*57843Smckusick return (sysctl_file(oldp, oldlenp)); 195*57843Smckusick case KERN_VNODE: 196*57843Smckusick return (sysctl_vnode(oldp, oldlenp)); 197*57843Smckusick case KERN_PROC: 198*57843Smckusick return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); 199*57843Smckusick default: 200*57843Smckusick return (EOPNOTSUPP); 20152405Storek } 202*57843Smckusick /* NOTREACHED */ 203*57843Smckusick } 204*57843Smckusick 205*57843Smckusick hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 206*57843Smckusick int *name; 207*57843Smckusick u_int namelen; 208*57843Smckusick void *oldp; 209*57843Smckusick u_int *oldlenp; 210*57843Smckusick void *newp; 211*57843Smckusick u_int newlen; 212*57843Smckusick { 213*57843Smckusick extern char machine[], cpu_model[]; 214*57843Smckusick 215*57843Smckusick /* all sysctl names at this level are terminal */ 216*57843Smckusick if (namelen != 1) 217*57843Smckusick return (ENOTDIR); /* overloaded */ 218*57843Smckusick 219*57843Smckusick switch (name[0]) { 220*57843Smckusick case HW_MACHINE: 221*57843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 222*57843Smckusick case HW_MODEL: 223*57843Smckusick return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 224*57843Smckusick case HW_NCPU: 225*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ 226*57843Smckusick case HW_CPUSPEED: 227*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed)); 228*57843Smckusick case HW_PHYSMEM: 229*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 230*57843Smckusick case HW_USERMEM: 231*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, 232*57843Smckusick ctob(physmem - cnt.v_wire_count))); 233*57843Smckusick case HW_PAGESIZE: 234*57843Smckusick return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 235*57843Smckusick default: 236*57843Smckusick return (EOPNOTSUPP); 237*57843Smckusick } 238*57843Smckusick /* NOTREACHED */ 239*57843Smckusick } 240*57843Smckusick 241*57843Smckusick /* 242*57843Smckusick * Validate parameters and get old / set new parameters 243*57843Smckusick * for an integer-valued sysctl function. 244*57843Smckusick */ 245*57843Smckusick sysctl_int(oldp, oldlenp, newp, newlen, valp) 246*57843Smckusick void *oldp; 247*57843Smckusick u_int *oldlenp; 248*57843Smckusick void *newp; 249*57843Smckusick u_int newlen; 250*57843Smckusick int *valp; 251*57843Smckusick { 252*57843Smckusick int error = 0; 253*57843Smckusick 254*57843Smckusick if (oldp && *oldlenp < sizeof(int)) 255*57843Smckusick return (ENOMEM); 256*57843Smckusick if (newp && newlen != sizeof(int)) 257*57843Smckusick return (EINVAL); 258*57843Smckusick *oldlenp = sizeof(int); 259*57843Smckusick if (oldp) 260*57843Smckusick error = copyout(valp, oldp, sizeof(int)); 261*57843Smckusick if (error == 0 && newp) 262*57843Smckusick error = copyin(newp, valp, sizeof(int)); 26343444Smckusick return (error); 26439963Smarc } 26539963Smarc 266*57843Smckusick /* 267*57843Smckusick * As above, but read-only. 268*57843Smckusick */ 269*57843Smckusick sysctl_rdint(oldp, oldlenp, newp, val) 270*57843Smckusick void *oldp; 271*57843Smckusick u_int *oldlenp; 272*57843Smckusick void *newp; 273*57843Smckusick int val; 274*57843Smckusick { 275*57843Smckusick int error = 0; 276*57843Smckusick 277*57843Smckusick if (oldp && *oldlenp < sizeof(int)) 278*57843Smckusick return (ENOMEM); 279*57843Smckusick if (newp) 280*57843Smckusick return (EPERM); 281*57843Smckusick *oldlenp = sizeof(int); 282*57843Smckusick if (oldp) 283*57843Smckusick error = copyout((caddr_t)&val, oldp, sizeof(int)); 284*57843Smckusick return (error); 285*57843Smckusick } 286*57843Smckusick 287*57843Smckusick /* 288*57843Smckusick * Validate parameters and get old / set new parameters 289*57843Smckusick * for a string-valued sysctl function. 290*57843Smckusick */ 291*57843Smckusick sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) 292*57843Smckusick void *oldp; 293*57843Smckusick u_int *oldlenp; 294*57843Smckusick void *newp; 295*57843Smckusick u_int newlen; 296*57843Smckusick char *str; 297*57843Smckusick int maxlen; 298*57843Smckusick { 299*57843Smckusick int len, error = 0; 300*57843Smckusick 301*57843Smckusick len = strlen(str) + 1; 302*57843Smckusick if (oldp && *oldlenp < len) 303*57843Smckusick return (ENOMEM); 304*57843Smckusick if (newp && newlen >= maxlen) 305*57843Smckusick return (EINVAL); 306*57843Smckusick *oldlenp = len; 307*57843Smckusick if (oldp) 308*57843Smckusick error = copyout(str, oldp, len); 309*57843Smckusick if (error == 0 && newp) { 310*57843Smckusick error = copyin(newp, str, newlen); 311*57843Smckusick str[newlen] = 0; 312*57843Smckusick } 313*57843Smckusick return (error); 314*57843Smckusick } 315*57843Smckusick 316*57843Smckusick /* 317*57843Smckusick * As above, but read-only. 318*57843Smckusick */ 319*57843Smckusick sysctl_rdstring(oldp, oldlenp, newp, str) 320*57843Smckusick void *oldp; 321*57843Smckusick u_int *oldlenp; 322*57843Smckusick void *newp; 323*57843Smckusick char *str; 324*57843Smckusick { 325*57843Smckusick int len, error = 0; 326*57843Smckusick 327*57843Smckusick len = strlen(str) + 1; 328*57843Smckusick if (oldp && *oldlenp < len) 329*57843Smckusick return (ENOMEM); 330*57843Smckusick if (newp) 331*57843Smckusick return (EPERM); 332*57843Smckusick *oldlenp = len; 333*57843Smckusick if (oldp) 334*57843Smckusick error = copyout(str, oldp, len); 335*57843Smckusick return (error); 336*57843Smckusick } 337*57843Smckusick 338*57843Smckusick /* 339*57843Smckusick * Validate parameters and get old parameters 340*57843Smckusick * for a structure oriented sysctl function. 341*57843Smckusick */ 342*57843Smckusick sysctl_rdstruct(oldp, oldlenp, newp, sp, len) 343*57843Smckusick void *oldp; 344*57843Smckusick u_int *oldlenp; 345*57843Smckusick void *newp; 346*57843Smckusick void *sp; 347*57843Smckusick int len; 348*57843Smckusick { 349*57843Smckusick int error = 0; 350*57843Smckusick 351*57843Smckusick if (oldp && *oldlenp < len) 352*57843Smckusick return (ENOMEM); 353*57843Smckusick if (newp) 354*57843Smckusick return (EPERM); 355*57843Smckusick *oldlenp = len; 356*57843Smckusick if (oldp) 357*57843Smckusick error = copyout(sp, oldp, len); 358*57843Smckusick return (error); 359*57843Smckusick } 360*57843Smckusick 361*57843Smckusick /* 362*57843Smckusick * Get file structures. 363*57843Smckusick */ 364*57843Smckusick sysctl_file(where, sizep) 365*57843Smckusick char *where; 366*57843Smckusick int *sizep; 367*57843Smckusick { 368*57843Smckusick int buflen, error; 369*57843Smckusick struct file *fp; 370*57843Smckusick char *start = where; 371*57843Smckusick 372*57843Smckusick buflen = *sizep; 373*57843Smckusick if (where == NULL) { 374*57843Smckusick /* 375*57843Smckusick * overestimate by 10 files 376*57843Smckusick */ 377*57843Smckusick *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 378*57843Smckusick return (0); 379*57843Smckusick } 380*57843Smckusick 381*57843Smckusick /* 382*57843Smckusick * first copyout filehead 383*57843Smckusick */ 384*57843Smckusick if (buflen < sizeof(filehead)) { 385*57843Smckusick *sizep = 0; 386*57843Smckusick return (0); 387*57843Smckusick } 388*57843Smckusick if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) 389*57843Smckusick return (error); 390*57843Smckusick buflen += sizeof(filehead); 391*57843Smckusick where += sizeof(filehead); 392*57843Smckusick 393*57843Smckusick /* 394*57843Smckusick * followed by an array of file structures 395*57843Smckusick */ 396*57843Smckusick for (fp = filehead; fp != NULL; fp = fp->f_filef) { 397*57843Smckusick if (buflen < sizeof(struct file)) { 398*57843Smckusick *sizep = where - start; 399*57843Smckusick return (ENOMEM); 400*57843Smckusick } 401*57843Smckusick if (error = copyout((caddr_t)fp, where, sizeof (struct file))) 402*57843Smckusick return (error); 403*57843Smckusick buflen -= sizeof(struct file); 404*57843Smckusick where += sizeof(struct file); 405*57843Smckusick } 406*57843Smckusick *sizep = where - start; 407*57843Smckusick return (0); 408*57843Smckusick } 409*57843Smckusick 41039963Smarc /* 41139963Smarc * try over estimating by 5 procs 41239963Smarc */ 413*57843Smckusick #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 41439963Smarc 415*57843Smckusick sysctl_doproc(name, namelen, where, sizep) 416*57843Smckusick int *name; 417*57843Smckusick int namelen; 41839963Smarc char *where; 419*57843Smckusick int *sizep; 42039963Smarc { 42139963Smarc register struct proc *p; 42243419Smarc register struct kinfo_proc *dp = (struct kinfo_proc *)where; 423*57843Smckusick register int needed = 0; 424*57843Smckusick int buflen = where != NULL ? *sizep : 0; 42539963Smarc int doingzomb; 42640067Smarc struct eproc eproc; 42739963Smarc int error = 0; 42839963Smarc 429*57843Smckusick if (namelen != 2) 430*57843Smckusick return (EINVAL); 43154755Storek p = (struct proc *)allproc; 43239963Smarc doingzomb = 0; 43339963Smarc again: 43439963Smarc for (; p != NULL; p = p->p_nxt) { 43553819Smckusick /* 43653819Smckusick * Skip embryonic processes. 43753819Smckusick */ 43853819Smckusick if (p->p_stat == SIDL) 43953819Smckusick continue; 44039963Smarc /* 44139963Smarc * TODO - make more efficient (see notes below). 44239963Smarc * do by session. 44339963Smarc */ 444*57843Smckusick switch (name[0]) { 44539963Smarc 446*57843Smckusick case KERN_PROC_PID: 44739963Smarc /* could do this with just a lookup */ 448*57843Smckusick if (p->p_pid != (pid_t)name[1]) 44939963Smarc continue; 45039963Smarc break; 45139963Smarc 452*57843Smckusick case KERN_PROC_PGRP: 45339963Smarc /* could do this by traversing pgrp */ 454*57843Smckusick if (p->p_pgrp->pg_id != (pid_t)name[1]) 45539963Smarc continue; 45639963Smarc break; 45739963Smarc 458*57843Smckusick case KERN_PROC_TTY: 45939963Smarc if ((p->p_flag&SCTTY) == 0 || 46039963Smarc p->p_session->s_ttyp == NULL || 461*57843Smckusick p->p_session->s_ttyp->t_dev != (dev_t)name[1]) 46239963Smarc continue; 46339963Smarc break; 46439963Smarc 465*57843Smckusick case KERN_PROC_UID: 466*57843Smckusick if (p->p_ucred->cr_uid != (uid_t)name[1]) 46739963Smarc continue; 46839963Smarc break; 46939963Smarc 470*57843Smckusick case KERN_PROC_RUID: 471*57843Smckusick if (p->p_cred->p_ruid != (uid_t)name[1]) 47239963Smarc continue; 47339963Smarc break; 47439963Smarc } 475*57843Smckusick if (buflen >= sizeof(struct kinfo_proc)) { 47648407Skarels fill_eproc(p, &eproc); 47743419Smarc if (error = copyout((caddr_t)p, &dp->kp_proc, 478*57843Smckusick sizeof(struct proc))) 47939963Smarc return (error); 48043419Smarc if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, 481*57843Smckusick sizeof(eproc))) 48239963Smarc return (error); 48343419Smarc dp++; 484*57843Smckusick buflen -= sizeof(struct kinfo_proc); 48539963Smarc } 486*57843Smckusick needed += sizeof(struct kinfo_proc); 48739963Smarc } 48839963Smarc if (doingzomb == 0) { 48939963Smarc p = zombproc; 49039963Smarc doingzomb++; 49139963Smarc goto again; 49239963Smarc } 493*57843Smckusick if (where != NULL) { 494*57843Smckusick *sizep = (caddr_t)dp - where; 495*57843Smckusick if (needed > *sizep) 496*57843Smckusick return (ENOMEM); 497*57843Smckusick } else { 498*57843Smckusick needed += KERN_PROCSLOP; 499*57843Smckusick *sizep = needed; 500*57843Smckusick } 50139963Smarc return (0); 50239963Smarc } 50348407Skarels 50448407Skarels /* 50548407Skarels * Fill in an eproc structure for the specified process. 50648407Skarels */ 50748407Skarels void 50848407Skarels fill_eproc(p, ep) 50948407Skarels register struct proc *p; 51048407Skarels register struct eproc *ep; 51148407Skarels { 51248407Skarels register struct tty *tp; 51348407Skarels 51448407Skarels ep->e_paddr = p; 51548407Skarels ep->e_sess = p->p_pgrp->pg_session; 51648407Skarels ep->e_pcred = *p->p_cred; 51748407Skarels ep->e_ucred = *p->p_ucred; 51852405Storek if (p->p_stat == SIDL || p->p_stat == SZOMB) { 51952405Storek ep->e_vm.vm_rssize = 0; 52052405Storek ep->e_vm.vm_tsize = 0; 52152405Storek ep->e_vm.vm_dsize = 0; 52252405Storek ep->e_vm.vm_ssize = 0; 52352405Storek #ifndef sparc 52452405Storek /* ep->e_vm.vm_pmap = XXX; */ 52552405Storek #endif 52652405Storek } else { 52752405Storek register struct vmspace *vm = p->p_vmspace; 52852405Storek 52952405Storek ep->e_vm.vm_rssize = vm->vm_rssize; 53052405Storek ep->e_vm.vm_tsize = vm->vm_tsize; 53152405Storek ep->e_vm.vm_dsize = vm->vm_dsize; 53252405Storek ep->e_vm.vm_ssize = vm->vm_ssize; 53352405Storek #ifndef sparc 53452405Storek ep->e_vm.vm_pmap = vm->vm_pmap; 53552405Storek #endif 53652405Storek } 53749141Skarels if (p->p_pptr) 53849141Skarels ep->e_ppid = p->p_pptr->p_pid; 53949141Skarels else 54049141Skarels ep->e_ppid = 0; 54148407Skarels ep->e_pgid = p->p_pgrp->pg_id; 54248407Skarels ep->e_jobc = p->p_pgrp->pg_jobc; 54348407Skarels if ((p->p_flag&SCTTY) && 54448407Skarels (tp = ep->e_sess->s_ttyp)) { 54548407Skarels ep->e_tdev = tp->t_dev; 54650022Skarels ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 54748407Skarels ep->e_tsess = tp->t_session; 54848407Skarels } else 54948407Skarels ep->e_tdev = NODEV; 55048407Skarels ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 55148407Skarels if (SESS_LEADER(p)) 55248407Skarels ep->e_flag |= EPROC_SLEADER; 55348407Skarels if (p->p_wmesg) 55448407Skarels strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 55548407Skarels ep->e_xsize = ep->e_xrssize = 0; 55648407Skarels ep->e_xccount = ep->e_xswrss = 0; 55748407Skarels } 55850149Smarc 559*57843Smckusick #ifdef COMPAT_43 560*57843Smckusick #include <sys/kinfo.h> 561*57843Smckusick #include <sys/socket.h> 562*57843Smckusick 563*57843Smckusick struct getkerninfo_args { 564*57843Smckusick int op; 565*57843Smckusick char *where; 566*57843Smckusick int *size; 567*57843Smckusick int arg; 568*57843Smckusick }; 569*57843Smckusick 570*57843Smckusick getkerninfo(p, uap, retval) 571*57843Smckusick struct proc *p; 572*57843Smckusick register struct getkerninfo_args *uap; 573*57843Smckusick int *retval; 57450149Smarc { 575*57843Smckusick int error, name[5]; 576*57843Smckusick u_int size; 57750149Smarc 578*57843Smckusick if (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size))) 579*57843Smckusick return (error); 58050149Smarc 581*57843Smckusick switch (ki_type(uap->op)) { 58250149Smarc 583*57843Smckusick case KINFO_RT: 584*57843Smckusick name[0] = PF_ROUTE; 585*57843Smckusick name[1] = 0; 586*57843Smckusick name[2] = (uap->op & 0xff0000) >> 16; 587*57843Smckusick name[3] = uap->op & 0xff; 588*57843Smckusick name[4] = uap->arg; 589*57843Smckusick error = net_sysctl(name, 5, uap->where, &size, NULL, 0); 590*57843Smckusick break; 591*57843Smckusick 592*57843Smckusick case KINFO_VNODE: 593*57843Smckusick name[0] = KERN_VNODE; 594*57843Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0); 595*57843Smckusick break; 596*57843Smckusick 597*57843Smckusick case KINFO_PROC: 598*57843Smckusick name[0] = KERN_PROC; 599*57843Smckusick name[1] = uap->op & 0xff; 600*57843Smckusick name[2] = uap->arg; 601*57843Smckusick error = kern_sysctl(name, 3, uap->where, &size, NULL, 0); 602*57843Smckusick break; 603*57843Smckusick 604*57843Smckusick case KINFO_FILE: 605*57843Smckusick name[0] = KERN_FILE; 606*57843Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0); 607*57843Smckusick break; 608*57843Smckusick 609*57843Smckusick case KINFO_METER: 610*57843Smckusick name[0] = VM_METER; 611*57843Smckusick error = vm_sysctl(name, 1, uap->where, &size, NULL, 0); 612*57843Smckusick break; 613*57843Smckusick 614*57843Smckusick case KINFO_LOADAVG: 615*57843Smckusick name[0] = VM_LOADAVG; 616*57843Smckusick error = vm_sysctl(name, 1, uap->where, &size, NULL, 0); 617*57843Smckusick break; 618*57843Smckusick 619*57843Smckusick case KINFO_CLOCKRATE: 620*57843Smckusick name[0] = KERN_CLOCKRATE; 621*57843Smckusick error = kern_sysctl(name, 1, uap->where, &size, NULL, 0); 622*57843Smckusick break; 623*57843Smckusick 624*57843Smckusick default: 625*57843Smckusick return (EINVAL); 62650149Smarc } 627*57843Smckusick if (error) 628*57843Smckusick return (error); 629*57843Smckusick *retval = size; 630*57843Smckusick return (copyout((caddr_t)&size, (caddr_t)uap->size, sizeof(size))); 63150149Smarc } 632*57843Smckusick #endif /* COMPAT_43 */ 633