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