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