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