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