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