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