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