1 /* $NetBSD: kern_sysctl.c,v 1.8 1995/03/26 00:01:08 cgd Exp $ */ 2 3 /*- 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Mike Karels at Berkeley Software Design, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 39 */ 40 41 /* 42 * sysctl system call. 43 */ 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #include <sys/proc.h> 50 #include <sys/file.h> 51 #include <sys/vnode.h> 52 #include <sys/unistd.h> 53 #include <sys/buf.h> 54 #include <sys/ioctl.h> 55 #include <sys/tty.h> 56 #include <sys/disklabel.h> 57 #include <vm/vm.h> 58 #include <sys/sysctl.h> 59 60 #include <sys/mount.h> 61 #include <sys/syscallargs.h> 62 63 sysctlfn kern_sysctl; 64 sysctlfn hw_sysctl; 65 #ifdef DEBUG 66 sysctlfn debug_sysctl; 67 #endif 68 extern sysctlfn vm_sysctl; 69 extern sysctlfn fs_sysctl; 70 extern sysctlfn net_sysctl; 71 extern sysctlfn cpu_sysctl; 72 73 /* 74 * Locking and stats 75 */ 76 static struct sysctl_lock { 77 int sl_lock; 78 int sl_want; 79 int sl_locked; 80 } memlock; 81 82 int 83 __sysctl(p, uap, retval) 84 struct proc *p; 85 register struct __sysctl_args /* { 86 syscallarg(int *) name; 87 syscallarg(u_int) namelen; 88 syscallarg(void *) old; 89 syscallarg(size_t *) oldlenp; 90 syscallarg(void *) new; 91 syscallarg(size_t) newlen; 92 } */ *uap; 93 register_t *retval; 94 { 95 int error, dolock = 1; 96 size_t savelen, oldlen = 0; 97 sysctlfn *fn; 98 int name[CTL_MAXNAME]; 99 100 if (SCARG(uap, new) != NULL && 101 (error = suser(p->p_ucred, &p->p_acflag))) 102 return (error); 103 /* 104 * all top-level sysctl names are non-terminal 105 */ 106 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2) 107 return (EINVAL); 108 if (error = 109 copyin(SCARG(uap, name), &name, SCARG(uap, namelen) * sizeof(int))) 110 return (error); 111 112 switch (name[0]) { 113 case CTL_KERN: 114 fn = kern_sysctl; 115 if (name[2] != KERN_VNODE) /* XXX */ 116 dolock = 0; 117 break; 118 case CTL_HW: 119 fn = hw_sysctl; 120 break; 121 case CTL_VM: 122 fn = vm_sysctl; 123 break; 124 case CTL_NET: 125 fn = net_sysctl; 126 break; 127 #ifdef notyet 128 case CTL_FS: 129 fn = fs_sysctl; 130 break; 131 #endif 132 case CTL_MACHDEP: 133 fn = cpu_sysctl; 134 break; 135 #ifdef DEBUG 136 case CTL_DEBUG: 137 fn = debug_sysctl; 138 break; 139 #endif 140 default: 141 return (EOPNOTSUPP); 142 } 143 144 if (SCARG(uap, oldlenp) && 145 (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen)))) 146 return (error); 147 if (SCARG(uap, old) != NULL) { 148 if (!useracc(SCARG(uap, old), oldlen, B_WRITE)) 149 return (EFAULT); 150 while (memlock.sl_lock) { 151 memlock.sl_want = 1; 152 sleep((caddr_t)&memlock, PRIBIO+1); 153 memlock.sl_locked++; 154 } 155 memlock.sl_lock = 1; 156 if (dolock) 157 vslock(SCARG(uap, old), oldlen); 158 savelen = oldlen; 159 } 160 error = (*fn)(name + 1, SCARG(uap, namelen) - 1, SCARG(uap, old), 161 &oldlen, SCARG(uap, new), SCARG(uap, newlen), p); 162 if (SCARG(uap, old) != NULL) { 163 if (dolock) 164 vsunlock(SCARG(uap, old), savelen, B_WRITE); 165 memlock.sl_lock = 0; 166 if (memlock.sl_want) { 167 memlock.sl_want = 0; 168 wakeup((caddr_t)&memlock); 169 } 170 } 171 if (error) 172 return (error); 173 if (SCARG(uap, oldlenp)) 174 error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen)); 175 *retval = oldlen; 176 return (0); 177 } 178 179 /* 180 * Attributes stored in the kernel. 181 */ 182 char hostname[MAXHOSTNAMELEN]; 183 int hostnamelen; 184 char domainname[MAXHOSTNAMELEN]; 185 int domainnamelen; 186 long hostid; 187 #ifdef INSECURE 188 int securelevel = -1; 189 #else 190 int securelevel; 191 #endif 192 193 /* 194 * kernel related system variables. 195 */ 196 kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 197 int *name; 198 u_int namelen; 199 void *oldp; 200 size_t *oldlenp; 201 void *newp; 202 size_t newlen; 203 struct proc *p; 204 { 205 int error, level, inthostid; 206 extern char ostype[], osrelease[], version[]; 207 208 /* all sysctl names at this level are terminal */ 209 if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF)) 210 return (ENOTDIR); /* overloaded */ 211 212 switch (name[0]) { 213 case KERN_OSTYPE: 214 return (sysctl_rdstring(oldp, oldlenp, newp, ostype)); 215 case KERN_OSRELEASE: 216 return (sysctl_rdstring(oldp, oldlenp, newp, osrelease)); 217 case KERN_OSREV: 218 return (sysctl_rdint(oldp, oldlenp, newp, BSD)); 219 case KERN_VERSION: 220 return (sysctl_rdstring(oldp, oldlenp, newp, version)); 221 case KERN_MAXVNODES: 222 return(sysctl_int(oldp, oldlenp, newp, newlen, &desiredvnodes)); 223 case KERN_MAXPROC: 224 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc)); 225 case KERN_MAXFILES: 226 return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles)); 227 case KERN_ARGMAX: 228 return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX)); 229 case KERN_SECURELVL: 230 level = securelevel; 231 if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) || 232 newp == NULL) 233 return (error); 234 if (level < securelevel && p->p_pid != 1) 235 return (EPERM); 236 securelevel = level; 237 return (0); 238 case KERN_HOSTNAME: 239 error = sysctl_string(oldp, oldlenp, newp, newlen, 240 hostname, sizeof(hostname)); 241 if (newp && !error) 242 hostnamelen = newlen; 243 return (error); 244 case KERN_DOMAINNAME: 245 error = sysctl_string(oldp, oldlenp, newp, newlen, 246 domainname, sizeof(domainname)); 247 if (newp && !error) 248 domainnamelen = newlen; 249 return (error); 250 case KERN_HOSTID: 251 inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */ 252 error = sysctl_int(oldp, oldlenp, newp, newlen, &inthostid); 253 hostid = inthostid; 254 return (error); 255 case KERN_CLOCKRATE: 256 return (sysctl_clockrate(oldp, oldlenp)); 257 case KERN_BOOTTIME: 258 return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime, 259 sizeof(struct timeval))); 260 case KERN_VNODE: 261 return (sysctl_vnode(oldp, oldlenp)); 262 case KERN_PROC: 263 return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp)); 264 case KERN_FILE: 265 return (sysctl_file(oldp, oldlenp)); 266 #ifdef GPROF 267 case KERN_PROF: 268 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp, 269 newp, newlen)); 270 #endif 271 case KERN_POSIX1: 272 return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION)); 273 case KERN_NGROUPS: 274 return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX)); 275 case KERN_JOB_CONTROL: 276 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 277 case KERN_SAVED_IDS: 278 #ifdef _POSIX_SAVED_IDS 279 return (sysctl_rdint(oldp, oldlenp, newp, 1)); 280 #else 281 return (sysctl_rdint(oldp, oldlenp, newp, 0)); 282 #endif 283 case KERN_MAXPARTITIONS: 284 return (sysctl_rdint(oldp, oldlenp, newp, MAXPARTITIONS)); 285 default: 286 return (EOPNOTSUPP); 287 } 288 /* NOTREACHED */ 289 } 290 291 /* 292 * hardware related system variables. 293 */ 294 hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 295 int *name; 296 u_int namelen; 297 void *oldp; 298 size_t *oldlenp; 299 void *newp; 300 size_t newlen; 301 struct proc *p; 302 { 303 extern char machine[], cpu_model[]; 304 305 /* all sysctl names at this level are terminal */ 306 if (namelen != 1) 307 return (ENOTDIR); /* overloaded */ 308 309 switch (name[0]) { 310 case HW_MACHINE: 311 return (sysctl_rdstring(oldp, oldlenp, newp, machine)); 312 case HW_MODEL: 313 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 314 case HW_NCPU: 315 return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ 316 case HW_BYTEORDER: 317 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER)); 318 case HW_PHYSMEM: 319 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 320 case HW_USERMEM: 321 return (sysctl_rdint(oldp, oldlenp, newp, 322 ctob(physmem - cnt.v_wire_count))); 323 case HW_PAGESIZE: 324 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 325 default: 326 return (EOPNOTSUPP); 327 } 328 /* NOTREACHED */ 329 } 330 331 #ifdef DEBUG 332 /* 333 * Debugging related system variables. 334 */ 335 struct ctldebug debug0, debug1, debug2, debug3, debug4; 336 struct ctldebug debug5, debug6, debug7, debug8, debug9; 337 struct ctldebug debug10, debug11, debug12, debug13, debug14; 338 struct ctldebug debug15, debug16, debug17, debug18, debug19; 339 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 340 &debug0, &debug1, &debug2, &debug3, &debug4, 341 &debug5, &debug6, &debug7, &debug8, &debug9, 342 &debug10, &debug11, &debug12, &debug13, &debug14, 343 &debug15, &debug16, &debug17, &debug18, &debug19, 344 }; 345 int 346 debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 347 int *name; 348 u_int namelen; 349 void *oldp; 350 size_t *oldlenp; 351 void *newp; 352 size_t newlen; 353 struct proc *p; 354 { 355 struct ctldebug *cdp; 356 357 /* all sysctl names at this level are name and field */ 358 if (namelen != 2) 359 return (ENOTDIR); /* overloaded */ 360 cdp = debugvars[name[0]]; 361 if (cdp->debugname == 0) 362 return (EOPNOTSUPP); 363 switch (name[1]) { 364 case CTL_DEBUG_NAME: 365 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 366 case CTL_DEBUG_VALUE: 367 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 368 default: 369 return (EOPNOTSUPP); 370 } 371 /* NOTREACHED */ 372 } 373 #endif /* DEBUG */ 374 375 /* 376 * Validate parameters and get old / set new parameters 377 * for an integer-valued sysctl function. 378 */ 379 sysctl_int(oldp, oldlenp, newp, newlen, valp) 380 void *oldp; 381 size_t *oldlenp; 382 void *newp; 383 size_t newlen; 384 int *valp; 385 { 386 int error = 0; 387 388 if (oldp && *oldlenp < sizeof(int)) 389 return (ENOMEM); 390 if (newp && newlen != sizeof(int)) 391 return (EINVAL); 392 *oldlenp = sizeof(int); 393 if (oldp) 394 error = copyout(valp, oldp, sizeof(int)); 395 if (error == 0 && newp) 396 error = copyin(newp, valp, sizeof(int)); 397 return (error); 398 } 399 400 /* 401 * As above, but read-only. 402 */ 403 sysctl_rdint(oldp, oldlenp, newp, val) 404 void *oldp; 405 size_t *oldlenp; 406 void *newp; 407 int val; 408 { 409 int error = 0; 410 411 if (oldp && *oldlenp < sizeof(int)) 412 return (ENOMEM); 413 if (newp) 414 return (EPERM); 415 *oldlenp = sizeof(int); 416 if (oldp) 417 error = copyout((caddr_t)&val, oldp, sizeof(int)); 418 return (error); 419 } 420 421 /* 422 * Validate parameters and get old / set new parameters 423 * for a string-valued sysctl function. 424 */ 425 sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) 426 void *oldp; 427 size_t *oldlenp; 428 void *newp; 429 size_t newlen; 430 char *str; 431 int maxlen; 432 { 433 int len, error = 0; 434 435 len = strlen(str) + 1; 436 if (oldp && *oldlenp < len) 437 return (ENOMEM); 438 if (newp && newlen >= maxlen) 439 return (EINVAL); 440 if (oldp) { 441 *oldlenp = len; 442 error = copyout(str, oldp, len); 443 } 444 if (error == 0 && newp) { 445 error = copyin(newp, str, newlen); 446 str[newlen] = 0; 447 } 448 return (error); 449 } 450 451 /* 452 * As above, but read-only. 453 */ 454 sysctl_rdstring(oldp, oldlenp, newp, str) 455 void *oldp; 456 size_t *oldlenp; 457 void *newp; 458 char *str; 459 { 460 int len, error = 0; 461 462 len = strlen(str) + 1; 463 if (oldp && *oldlenp < len) 464 return (ENOMEM); 465 if (newp) 466 return (EPERM); 467 *oldlenp = len; 468 if (oldp) 469 error = copyout(str, oldp, len); 470 return (error); 471 } 472 473 /* 474 * Validate parameters and get old / set new parameters 475 * for a structure oriented sysctl function. 476 */ 477 sysctl_struct(oldp, oldlenp, newp, newlen, sp, len) 478 void *oldp; 479 size_t *oldlenp; 480 void *newp; 481 size_t newlen; 482 void *sp; 483 int len; 484 { 485 int error = 0; 486 487 if (oldp && *oldlenp < len) 488 return (ENOMEM); 489 if (newp && newlen > len) 490 return (EINVAL); 491 if (oldp) { 492 *oldlenp = len; 493 error = copyout(sp, oldp, len); 494 } 495 if (error == 0 && newp) 496 error = copyin(newp, sp, len); 497 return (error); 498 } 499 500 /* 501 * Validate parameters and get old parameters 502 * for a structure oriented sysctl function. 503 */ 504 sysctl_rdstruct(oldp, oldlenp, newp, sp, len) 505 void *oldp; 506 size_t *oldlenp; 507 void *newp, *sp; 508 int len; 509 { 510 int error = 0; 511 512 if (oldp && *oldlenp < len) 513 return (ENOMEM); 514 if (newp) 515 return (EPERM); 516 *oldlenp = len; 517 if (oldp) 518 error = copyout(sp, oldp, len); 519 return (error); 520 } 521 522 /* 523 * Get file structures. 524 */ 525 sysctl_file(where, sizep) 526 char *where; 527 size_t *sizep; 528 { 529 int buflen, error; 530 struct file *fp; 531 char *start = where; 532 533 buflen = *sizep; 534 if (where == NULL) { 535 /* 536 * overestimate by 10 files 537 */ 538 *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 539 return (0); 540 } 541 542 /* 543 * first copyout filehead 544 */ 545 if (buflen < sizeof(filehead)) { 546 *sizep = 0; 547 return (0); 548 } 549 if (error = copyout((caddr_t)&filehead, where, sizeof(filehead))) 550 return (error); 551 buflen -= sizeof(filehead); 552 where += sizeof(filehead); 553 554 /* 555 * followed by an array of file structures 556 */ 557 for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) { 558 if (buflen < sizeof(struct file)) { 559 *sizep = where - start; 560 return (ENOMEM); 561 } 562 if (error = copyout((caddr_t)fp, where, sizeof (struct file))) 563 return (error); 564 buflen -= sizeof(struct file); 565 where += sizeof(struct file); 566 } 567 *sizep = where - start; 568 return (0); 569 } 570 571 /* 572 * try over estimating by 5 procs 573 */ 574 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 575 576 sysctl_doproc(name, namelen, where, sizep) 577 int *name; 578 u_int namelen; 579 char *where; 580 size_t *sizep; 581 { 582 register struct proc *p; 583 register struct kinfo_proc *dp = (struct kinfo_proc *)where; 584 register int needed = 0; 585 int buflen = where != NULL ? *sizep : 0; 586 int doingzomb; 587 struct eproc eproc; 588 int error = 0; 589 590 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL)) 591 return (EINVAL); 592 p = allproc.lh_first; 593 doingzomb = 0; 594 again: 595 for (; p != 0; p = p->p_list.le_next) { 596 /* 597 * Skip embryonic processes. 598 */ 599 if (p->p_stat == SIDL) 600 continue; 601 /* 602 * TODO - make more efficient (see notes below). 603 * do by session. 604 */ 605 switch (name[0]) { 606 607 case KERN_PROC_PID: 608 /* could do this with just a lookup */ 609 if (p->p_pid != (pid_t)name[1]) 610 continue; 611 break; 612 613 case KERN_PROC_PGRP: 614 /* could do this by traversing pgrp */ 615 if (p->p_pgrp->pg_id != (pid_t)name[1]) 616 continue; 617 break; 618 619 case KERN_PROC_TTY: 620 if ((p->p_flag & P_CONTROLT) == 0 || 621 p->p_session->s_ttyp == NULL || 622 p->p_session->s_ttyp->t_dev != (dev_t)name[1]) 623 continue; 624 break; 625 626 case KERN_PROC_UID: 627 if (p->p_ucred->cr_uid != (uid_t)name[1]) 628 continue; 629 break; 630 631 case KERN_PROC_RUID: 632 if (p->p_cred->p_ruid != (uid_t)name[1]) 633 continue; 634 break; 635 } 636 if (buflen >= sizeof(struct kinfo_proc)) { 637 fill_eproc(p, &eproc); 638 if (error = copyout((caddr_t)p, &dp->kp_proc, 639 sizeof(struct proc))) 640 return (error); 641 if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, 642 sizeof(eproc))) 643 return (error); 644 dp++; 645 buflen -= sizeof(struct kinfo_proc); 646 } 647 needed += sizeof(struct kinfo_proc); 648 } 649 if (doingzomb == 0) { 650 p = zombproc.lh_first; 651 doingzomb++; 652 goto again; 653 } 654 if (where != NULL) { 655 *sizep = (caddr_t)dp - where; 656 if (needed > *sizep) 657 return (ENOMEM); 658 } else { 659 needed += KERN_PROCSLOP; 660 *sizep = needed; 661 } 662 return (0); 663 } 664 665 /* 666 * Fill in an eproc structure for the specified process. 667 */ 668 void 669 fill_eproc(p, ep) 670 register struct proc *p; 671 register struct eproc *ep; 672 { 673 register struct tty *tp; 674 675 ep->e_paddr = p; 676 ep->e_sess = p->p_pgrp->pg_session; 677 ep->e_pcred = *p->p_cred; 678 ep->e_ucred = *p->p_ucred; 679 if (p->p_stat == SIDL || p->p_stat == SZOMB) { 680 ep->e_vm.vm_rssize = 0; 681 ep->e_vm.vm_tsize = 0; 682 ep->e_vm.vm_dsize = 0; 683 ep->e_vm.vm_ssize = 0; 684 /* ep->e_vm.vm_pmap = XXX; */ 685 } else { 686 register struct vmspace *vm = p->p_vmspace; 687 688 #ifdef pmap_resident_count 689 ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/ 690 #else 691 ep->e_vm.vm_rssize = vm->vm_rssize; 692 #endif 693 ep->e_vm.vm_tsize = vm->vm_tsize; 694 ep->e_vm.vm_dsize = vm->vm_dsize; 695 ep->e_vm.vm_ssize = vm->vm_ssize; 696 ep->e_vm.vm_pmap = vm->vm_pmap; 697 } 698 if (p->p_pptr) 699 ep->e_ppid = p->p_pptr->p_pid; 700 else 701 ep->e_ppid = 0; 702 ep->e_pgid = p->p_pgrp->pg_id; 703 ep->e_jobc = p->p_pgrp->pg_jobc; 704 if ((p->p_flag & P_CONTROLT) && 705 (tp = ep->e_sess->s_ttyp)) { 706 ep->e_tdev = tp->t_dev; 707 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 708 ep->e_tsess = tp->t_session; 709 } else 710 ep->e_tdev = NODEV; 711 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 712 if (SESS_LEADER(p)) 713 ep->e_flag |= EPROC_SLEADER; 714 if (p->p_wmesg) 715 strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 716 ep->e_xsize = ep->e_xrssize = 0; 717 ep->e_xccount = ep->e_xswrss = 0; 718 } 719 720 #ifdef COMPAT_43 721 #include <sys/socket.h> 722 #define KINFO_PROC (0<<8) 723 #define KINFO_RT (1<<8) 724 #define KINFO_VNODE (2<<8) 725 #define KINFO_FILE (3<<8) 726 #define KINFO_METER (4<<8) 727 #define KINFO_LOADAVG (5<<8) 728 #define KINFO_CLOCKRATE (6<<8) 729 730 compat_43_getkerninfo(p, uap, retval) 731 struct proc *p; 732 register struct compat_43_getkerninfo_args /* { 733 syscallarg(int) op; 734 syscallarg(char *) where; 735 syscallarg(int *) size; 736 syscallarg(int) arg; 737 } */ *uap; 738 register_t *retval; 739 { 740 int error, name[5]; 741 size_t size; 742 743 if (SCARG(uap, size) && (error = copyin((caddr_t)SCARG(uap, size), 744 (caddr_t)&size, sizeof(size)))) 745 return (error); 746 747 switch (SCARG(uap, op) & 0xff00) { 748 749 case KINFO_RT: 750 name[0] = PF_ROUTE; 751 name[1] = 0; 752 name[2] = (SCARG(uap, op) & 0xff0000) >> 16; 753 name[3] = SCARG(uap, op) & 0xff; 754 name[4] = SCARG(uap, arg); 755 error = 756 net_sysctl(name, 5, SCARG(uap, where), &size, NULL, 0, p); 757 break; 758 759 case KINFO_VNODE: 760 name[0] = KERN_VNODE; 761 error = 762 kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); 763 break; 764 765 case KINFO_PROC: 766 name[0] = KERN_PROC; 767 name[1] = SCARG(uap, op) & 0xff; 768 name[2] = SCARG(uap, arg); 769 error = 770 kern_sysctl(name, 3, SCARG(uap, where), &size, NULL, 0, p); 771 break; 772 773 case KINFO_FILE: 774 name[0] = KERN_FILE; 775 error = 776 kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); 777 break; 778 779 case KINFO_METER: 780 name[0] = VM_METER; 781 error = 782 vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); 783 break; 784 785 case KINFO_LOADAVG: 786 name[0] = VM_LOADAVG; 787 error = 788 vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); 789 break; 790 791 case KINFO_CLOCKRATE: 792 name[0] = KERN_CLOCKRATE; 793 error = 794 kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); 795 break; 796 797 default: 798 return (EOPNOTSUPP); 799 } 800 if (error) 801 return (error); 802 *retval = size; 803 if (SCARG(uap, size)) 804 error = copyout((caddr_t)&size, (caddr_t)SCARG(uap, size), 805 sizeof(size)); 806 return (error); 807 } 808 #endif /* COMPAT_43 */ 809