kern_sysctl.c revision 1952
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.4 1994/08/08 00:30:03 wollman 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; 67 68/* 69 * Locking and stats 70 */ 71static struct sysctl_lock { 72 int sl_lock; 73 int sl_want; 74 int sl_locked; 75} memlock; 76 77struct sysctl_args { 78 int *name; 79 u_int namelen; 80 void *old; 81 size_t *oldlenp; 82 void *new; 83 size_t newlen; 84}; 85 86int 87__sysctl(p, uap, retval) 88 struct proc *p; 89 register struct sysctl_args *uap; 90 int *retval; 91{ 92 int error, dolock = 1; 93 u_int savelen = 0, oldlen = 0; 94 sysctlfn *fn; 95 int name[CTL_MAXNAME]; 96 97 if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) 98 return (error); 99 /* 100 * all top-level sysctl names are non-terminal 101 */ 102 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 103 return (EINVAL); 104 if (error = copyin(uap->name, &name, uap->namelen * sizeof(int))) 105 return (error); 106 107 switch (name[0]) { 108 case CTL_KERN: 109 fn = kern_sysctl; 110 if (name[2] != KERN_VNODE) /* XXX */ 111 dolock = 0; 112 break; 113 case CTL_HW: 114 fn = hw_sysctl; 115 break; 116 case CTL_VM: 117 fn = vm_sysctl; 118 break; 119 case CTL_NET: 120 fn = net_sysctl; 121 break; 122#ifdef notyet 123 case CTL_FS: 124 fn = fs_sysctl; 125 break; 126#endif 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 sleep((caddr_t)&memlock, PRIBIO+1); 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; 183extern int vfs_update_wakeup; 184extern int vfs_update_interval; 185 186/* 187 * kernel related system variables. 188 */ 189int 190kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 191 int *name; 192 u_int namelen; 193 void *oldp; 194 size_t *oldlenp; 195 void *newp; 196 size_t newlen; 197 struct proc *p; 198{ 199 int error, level, inthostid; 200 extern char ostype[], osrelease[], version[]; 201 202 /* all sysctl names at this level are terminal */ 203 if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF)) 204 return (ENOTDIR); /* overloaded */ 205 206 switch (name[0]) { 207 case KERN_OSTYPE: 208 return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 209 case KERN_OSRELEASE: 210 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 211 case KERN_OSREV: 212 return (sysctl_rdint(oldp, oldlenp, newp, BSD)); 213 case KERN_VERSION: 214 return (sysctl_rdstring(oldp, oldlenp, newp, version)); 215 case KERN_MAXVNODES: 216 return(sysctl_int(oldp, oldlenp, newp, newlen, &desiredvnodes)); 217 case KERN_MAXPROC: 218 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); 219 case KERN_MAXFILES: 220 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 221 case KERN_UPDATEINTERVAL: 222 /* 223 * NB: this simple-minded approach only works because 224 * `tsleep' takes a timeout argument of 0 as meaning 225 * `no timeout'. 226 */ 227 error = sysctl_int(oldp, oldlenp, newp, newlen, 228 &vfs_update_interval); 229 if(!error) { 230 wakeup(&vfs_update_wakeup); 231 } 232 return error; 233 case KERN_ARGMAX: 234 return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 235 case KERN_SECURELVL: 236 level = securelevel; 237 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 238 newp == NULL) 239 return (error); 240 if (level < securelevel && p->p_pid != 1) 241 return (EPERM); 242 securelevel = level; 243 return (0); 244 case KERN_HOSTNAME: 245 error = sysctl_string(oldp, oldlenp, newp, newlen, 246 hostname, sizeof(hostname)); 247 if (newp && !error) 248 hostnamelen = newlen; 249 return (error); 250 case KERN_DOMAINNAME: 251 error = sysctl_string(oldp, oldlenp, newp, newlen, 252 domainname, sizeof(domainname)); 253 if (newp && !error) 254 domainnamelen = newlen; 255 return (error); 256 case KERN_HOSTID: 257 inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */ 258 error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid); 259 hostid = inthostid; 260 return (error); 261 case KERN_CLOCKRATE: 262 return (sysctl_clockrate(oldp, oldlenp)); 263 case KERN_BOOTTIME: 264 return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime, 265 sizeof(struct timeval))); 266 case KERN_VNODE: 267 return (sysctl_vnode(oldp, oldlenp)); 268 case KERN_PROC: 269 return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); 270 case KERN_FILE: 271 return (sysctl_file(oldp, oldlenp)); 272#ifdef GPROF 273 case KERN_PROF: 274 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp, 275 newp, newlen)); 276#endif 277 case KERN_POSIX1: 278 return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 279 case KERN_NGROUPS: 280 return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX)); 281 case KERN_JOB_CONTROL: 282 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 283 case KERN_SAVED_IDS: 284#ifdef _POSIX_SAVED_IDS 285 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 286#else 287 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 288#endif 289 default: 290 return (EOPNOTSUPP); 291 } 292 /* NOTREACHED */ 293} 294 295/* 296 * hardware related system variables. 297 */ 298int 299hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 300 int *name; 301 u_int namelen; 302 void *oldp; 303 size_t *oldlenp; 304 void *newp; 305 size_t newlen; 306 struct proc *p; 307{ 308 extern char machine[], cpu_model[]; 309 310 /* all sysctl names at this level are terminal */ 311 if (namelen != 1) 312 return (ENOTDIR); /* overloaded */ 313 314 switch (name[0]) { 315 case HW_MACHINE: 316 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 317 case HW_MODEL: 318 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 319 case HW_NCPU: 320 return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ 321 case HW_BYTEORDER: 322 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER)); 323 case HW_PHYSMEM: 324 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 325 case HW_USERMEM: 326 return (sysctl_rdint(oldp, oldlenp, newp, 327 ctob(physmem - cnt.v_wire_count))); 328 case HW_PAGESIZE: 329 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 330 default: 331 return (EOPNOTSUPP); 332 } 333 /* NOTREACHED */ 334} 335 336#ifdef DEBUG 337/* 338 * Debugging related system variables. 339 */ 340struct ctldebug debug0, debug1, debug2, debug3, debug4; 341struct ctldebug debug5, debug6, debug7, debug8, debug9; 342struct ctldebug debug10, debug11, debug12, debug13, debug14; 343struct ctldebug debug15, debug16, debug17, debug18, debug19; 344static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 345 &debug0, &debug1, &debug2, &debug3, &debug4, 346 &debug5, &debug6, &debug7, &debug8, &debug9, 347 &debug10, &debug11, &debug12, &debug13, &debug14, 348 &debug15, &debug16, &debug17, &debug18, &debug19, 349}; 350int 351debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 352 int *name; 353 u_int namelen; 354 void *oldp; 355 size_t *oldlenp; 356 void *newp; 357 size_t newlen; 358 struct proc *p; 359{ 360 struct ctldebug *cdp; 361 362 /* all sysctl names at this level are name and field */ 363 if (namelen != 2) 364 return (ENOTDIR); /* overloaded */ 365 cdp = debugvars[name[0]]; 366 if (cdp->debugname == 0) 367 return (EOPNOTSUPP); 368 switch (name[1]) { 369 case CTL_DEBUG_NAME: 370 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 371 case CTL_DEBUG_VALUE: 372 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 373 default: 374 return (EOPNOTSUPP); 375 } 376 /* NOTREACHED */ 377} 378#endif /* DEBUG */ 379 380/* 381 * Validate parameters and get old / set new parameters 382 * for an integer-valued sysctl function. 383 */ 384int 385sysctl_int(oldp, oldlenp, newp, newlen, valp) 386 void *oldp; 387 size_t *oldlenp; 388 void *newp; 389 size_t newlen; 390 int *valp; 391{ 392 int error = 0; 393 394 if (oldp && *oldlenp < sizeof(int)) 395 return (ENOMEM); 396 if (newp && newlen != sizeof(int)) 397 return (EINVAL); 398 *oldlenp = sizeof(int); 399 if (oldp) 400 error = copyout(valp, oldp, sizeof(int)); 401 if (error == 0 && newp) 402 error = copyin(newp, valp, sizeof(int)); 403 return (error); 404} 405 406/* 407 * As above, but read-only. 408 */ 409int 410sysctl_rdint(oldp, oldlenp, newp, val) 411 void *oldp; 412 size_t *oldlenp; 413 void *newp; 414 int val; 415{ 416 int error = 0; 417 418 if (oldp && *oldlenp < sizeof(int)) 419 return (ENOMEM); 420 if (newp) 421 return (EPERM); 422 *oldlenp = sizeof(int); 423 if (oldp) 424 error = copyout((caddr_t)&val, oldp, sizeof(int)); 425 return (error); 426} 427 428/* 429 * Validate parameters and get old / set new parameters 430 * for a string-valued sysctl function. 431 */ 432int 433sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) 434 void *oldp; 435 size_t *oldlenp; 436 void *newp; 437 size_t newlen; 438 char *str; 439 int maxlen; 440{ 441 int len, error = 0; 442 443 len = strlen(str) + 1; 444 if (oldp && *oldlenp < len) 445 return (ENOMEM); 446 if (newp && newlen >= maxlen) 447 return (EINVAL); 448 if (oldp) { 449 *oldlenp = len; 450 error = copyout(str, oldp, len); 451 } 452 if (error == 0 && newp) { 453 error = copyin(newp, str, newlen); 454 str[newlen] = 0; 455 } 456 return (error); 457} 458 459/* 460 * As above, but read-only. 461 */ 462int 463sysctl_rdstring(oldp, oldlenp, newp, str) 464 void *oldp; 465 size_t *oldlenp; 466 void *newp; 467 char *str; 468{ 469 int len, error = 0; 470 471 len = strlen(str) + 1; 472 if (oldp && *oldlenp < len) 473 return (ENOMEM); 474 if (newp) 475 return (EPERM); 476 *oldlenp = len; 477 if (oldp) 478 error = copyout(str, oldp, len); 479 return (error); 480} 481 482/* 483 * Validate parameters and get old / set new parameters 484 * for a structure oriented sysctl function. 485 */ 486int 487sysctl_struct(oldp, oldlenp, newp, newlen, sp, len) 488 void *oldp; 489 size_t *oldlenp; 490 void *newp; 491 size_t newlen; 492 void *sp; 493 int len; 494{ 495 int error = 0; 496 497 if (oldp && *oldlenp < len) 498 return (ENOMEM); 499 if (newp && newlen > len) 500 return (EINVAL); 501 if (oldp) { 502 *oldlenp = len; 503 error = copyout(sp, oldp, len); 504 } 505 if (error == 0 && newp) 506 error = copyin(newp, sp, len); 507 return (error); 508} 509 510/* 511 * Validate parameters and get old parameters 512 * for a structure oriented sysctl function. 513 */ 514int 515sysctl_rdstruct(oldp, oldlenp, newp, sp, len) 516 void *oldp; 517 size_t *oldlenp; 518 void *newp, *sp; 519 int len; 520{ 521 int error = 0; 522 523 if (oldp && *oldlenp < len) 524 return (ENOMEM); 525 if (newp) 526 return (EPERM); 527 *oldlenp = len; 528 if (oldp) 529 error = copyout(sp, oldp, len); 530 return (error); 531} 532 533/* 534 * Get file structures. 535 */ 536int 537sysctl_file(where, sizep) 538 char *where; 539 size_t *sizep; 540{ 541 int buflen, error; 542 struct file *fp; 543 char *start = where; 544 545 buflen = *sizep; 546 if (where == NULL) { 547 /* 548 * overestimate by 10 files 549 */ 550 *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 551 return (0); 552 } 553 554 /* 555 * first copyout filehead 556 */ 557 if (buflen < sizeof(filehead)) { 558 *sizep = 0; 559 return (0); 560 } 561 if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) 562 return (error); 563 buflen -= sizeof(filehead); 564 where += sizeof(filehead); 565 566 /* 567 * followed by an array of file structures 568 */ 569 for (fp = filehead; fp != NULL; fp = fp->f_filef) { 570 if (buflen < sizeof(struct file)) { 571 *sizep = where - start; 572 return (ENOMEM); 573 } 574 if (error = copyout((caddr_t)fp, where, sizeof (struct file))) 575 return (error); 576 buflen -= sizeof(struct file); 577 where += sizeof(struct file); 578 } 579 *sizep = where - start; 580 return (0); 581} 582 583/* 584 * try over estimating by 5 procs 585 */ 586#define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 587 588int 589sysctl_doproc(name, namelen, where, sizep) 590 int *name; 591 u_int namelen; 592 char *where; 593 size_t *sizep; 594{ 595 register struct proc *p; 596 register struct kinfo_proc *dp = (struct kinfo_proc *)where; 597 register int needed = 0; 598 int buflen = where != NULL ? *sizep : 0; 599 int doingzomb; 600 struct eproc eproc; 601 int error = 0; 602 603 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL)) 604 return (EINVAL); 605 p = (struct proc *)allproc; 606 doingzomb = 0; 607again: 608 for (; p != NULL; p = p->p_next) { 609 /* 610 * Skip embryonic processes. 611 */ 612 if (p->p_stat == SIDL) 613 continue; 614 /* 615 * TODO - make more efficient (see notes below). 616 * do by session. 617 */ 618 switch (name[0]) { 619 620 case KERN_PROC_PID: 621 /* could do this with just a lookup */ 622 if (p->p_pid != (pid_t)name[1]) 623 continue; 624 break; 625 626 case KERN_PROC_PGRP: 627 /* could do this by traversing pgrp */ 628 if (p->p_pgrp->pg_id != (pid_t)name[1]) 629 continue; 630 break; 631 632 case KERN_PROC_TTY: 633 if ((p->p_flag & P_CONTROLT) == 0 || 634 p->p_session->s_ttyp == NULL || 635 p->p_session->s_ttyp->t_dev != (dev_t)name[1]) 636 continue; 637 break; 638 639 case KERN_PROC_UID: 640 if (p->p_ucred->cr_uid != (uid_t)name[1]) 641 continue; 642 break; 643 644 case KERN_PROC_RUID: 645 if (p->p_cred->p_ruid != (uid_t)name[1]) 646 continue; 647 break; 648 } 649 if (buflen >= sizeof(struct kinfo_proc)) { 650 fill_eproc(p, &eproc); 651 if (error = copyout((caddr_t)p, &dp->kp_proc, 652 sizeof(struct proc))) 653 return (error); 654 if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, 655 sizeof(eproc))) 656 return (error); 657 dp++; 658 buflen -= sizeof(struct kinfo_proc); 659 } 660 needed += sizeof(struct kinfo_proc); 661 } 662 if (doingzomb == 0) { 663 p = zombproc; 664 doingzomb++; 665 goto again; 666 } 667 if (where != NULL) { 668 *sizep = (caddr_t)dp - where; 669 if (needed > *sizep) 670 return (ENOMEM); 671 } else { 672 needed += KERN_PROCSLOP; 673 *sizep = needed; 674 } 675 return (0); 676} 677 678/* 679 * Fill in an eproc structure for the specified process. 680 */ 681void 682fill_eproc(p, ep) 683 register struct proc *p; 684 register struct eproc *ep; 685{ 686 register struct tty *tp; 687 688 ep->e_paddr = p; 689 ep->e_sess = p->p_pgrp->pg_session; 690 ep->e_pcred = *p->p_cred; 691 ep->e_ucred = *p->p_ucred; 692 if (p->p_stat == SIDL || p->p_stat == SZOMB) { 693 ep->e_vm.vm_rssize = 0; 694 ep->e_vm.vm_tsize = 0; 695 ep->e_vm.vm_dsize = 0; 696 ep->e_vm.vm_ssize = 0; 697#ifndef sparc 698 /* ep->e_vm.vm_pmap = XXX; */ 699#endif 700 } else { 701 register struct vmspace *vm = p->p_vmspace; 702 703#ifdef pmap_resident_count 704 ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/ 705#else 706 ep->e_vm.vm_rssize = vm->vm_rssize; 707#endif 708 ep->e_vm.vm_tsize = vm->vm_tsize; 709 ep->e_vm.vm_dsize = vm->vm_dsize; 710 ep->e_vm.vm_ssize = vm->vm_ssize; 711#ifndef sparc 712 ep->e_vm.vm_pmap = vm->vm_pmap; 713#endif 714 } 715 if (p->p_pptr) 716 ep->e_ppid = p->p_pptr->p_pid; 717 else 718 ep->e_ppid = 0; 719 ep->e_pgid = p->p_pgrp->pg_id; 720 ep->e_jobc = p->p_pgrp->pg_jobc; 721 if ((p->p_flag & P_CONTROLT) && 722 (tp = ep->e_sess->s_ttyp)) { 723 ep->e_tdev = tp->t_dev; 724 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 725 ep->e_tsess = tp->t_session; 726 } else 727 ep->e_tdev = NODEV; 728 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 729 if (SESS_LEADER(p)) 730 ep->e_flag |= EPROC_SLEADER; 731 if (p->p_wmesg) 732 strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 733 ep->e_xsize = ep->e_xrssize = 0; 734 ep->e_xccount = ep->e_xswrss = 0; 735} 736 737#ifdef COMPAT_43 738#include <sys/socket.h> 739#define KINFO_PROC (0<<8) 740#define KINFO_RT (1<<8) 741#define KINFO_VNODE (2<<8) 742#define KINFO_FILE (3<<8) 743#define KINFO_METER (4<<8) 744#define KINFO_LOADAVG (5<<8) 745#define KINFO_CLOCKRATE (6<<8) 746 747struct getkerninfo_args { 748 int op; 749 char *where; 750 int *size; 751 int arg; 752}; 753 754int 755ogetkerninfo(p, uap, retval) 756 struct proc *p; 757 register struct getkerninfo_args *uap; 758 int *retval; 759{ 760 int error, name[5]; 761 u_int size; 762 763 if (uap->size && 764 (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size)))) 765 return (error); 766 767 switch (uap->op & 0xff00) { 768 769 case KINFO_RT: 770 name[0] = PF_ROUTE; 771 name[1] = 0; 772 name[2] = (uap->op & 0xff0000) >> 16; 773 name[3] = uap->op & 0xff; 774 name[4] = uap->arg; 775 error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p); 776 break; 777 778 case KINFO_VNODE: 779 name[0] = KERN_VNODE; 780 error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 781 break; 782 783 case KINFO_PROC: 784 name[0] = KERN_PROC; 785 name[1] = uap->op & 0xff; 786 name[2] = uap->arg; 787 error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p); 788 break; 789 790 case KINFO_FILE: 791 name[0] = KERN_FILE; 792 error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 793 break; 794 795 case KINFO_METER: 796 name[0] = VM_METER; 797 error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); 798 break; 799 800 case KINFO_LOADAVG: 801 name[0] = VM_LOADAVG; 802 error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); 803 break; 804 805 case KINFO_CLOCKRATE: 806 name[0] = KERN_CLOCKRATE; 807 error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); 808 break; 809 810 default: 811 return (EOPNOTSUPP); 812 } 813 if (error) 814 return (error); 815 *retval = size; 816 if (uap->size) 817 error = copyout((caddr_t)&size, (caddr_t)uap->size, 818 sizeof(size)); 819 return (error); 820} 821#endif /* COMPAT_43 */ 822