1 /* $NetBSD: kern_sysctl.c,v 1.27 1997/06/06 23:14:36 veego 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[], machine_arch[], 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_MACHINE_ARCH: 342 return (sysctl_rdstring(oldp, oldlenp, newp, machine_arch)); 343 case HW_MODEL: 344 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model)); 345 case HW_NCPU: 346 return (sysctl_rdint(oldp, oldlenp, newp, 1)); /* XXX */ 347 case HW_BYTEORDER: 348 return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER)); 349 case HW_PHYSMEM: 350 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem))); 351 case HW_USERMEM: 352 return (sysctl_rdint(oldp, oldlenp, newp, 353 ctob(physmem - cnt.v_wire_count))); 354 case HW_PAGESIZE: 355 return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE)); 356 default: 357 return (EOPNOTSUPP); 358 } 359 /* NOTREACHED */ 360 } 361 362 #ifdef DEBUG 363 /* 364 * Debugging related system variables. 365 */ 366 struct ctldebug debug0, debug1, debug2, debug3, debug4; 367 struct ctldebug debug5, debug6, debug7, debug8, debug9; 368 struct ctldebug debug10, debug11, debug12, debug13, debug14; 369 struct ctldebug debug15, debug16, debug17, debug18, debug19; 370 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 371 &debug0, &debug1, &debug2, &debug3, &debug4, 372 &debug5, &debug6, &debug7, &debug8, &debug9, 373 &debug10, &debug11, &debug12, &debug13, &debug14, 374 &debug15, &debug16, &debug17, &debug18, &debug19, 375 }; 376 int 377 debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 378 int *name; 379 u_int namelen; 380 void *oldp; 381 size_t *oldlenp; 382 void *newp; 383 size_t newlen; 384 struct proc *p; 385 { 386 struct ctldebug *cdp; 387 388 /* all sysctl names at this level are name and field */ 389 if (namelen != 2) 390 return (ENOTDIR); /* overloaded */ 391 cdp = debugvars[name[0]]; 392 if (cdp->debugname == 0) 393 return (EOPNOTSUPP); 394 switch (name[1]) { 395 case CTL_DEBUG_NAME: 396 return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname)); 397 case CTL_DEBUG_VALUE: 398 return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar)); 399 default: 400 return (EOPNOTSUPP); 401 } 402 /* NOTREACHED */ 403 } 404 #endif /* DEBUG */ 405 406 /* 407 * Validate parameters and get old / set new parameters 408 * for an integer-valued sysctl function. 409 */ 410 int 411 sysctl_int(oldp, oldlenp, newp, newlen, valp) 412 void *oldp; 413 size_t *oldlenp; 414 void *newp; 415 size_t newlen; 416 int *valp; 417 { 418 int error = 0; 419 420 if (oldp && *oldlenp < sizeof(int)) 421 return (ENOMEM); 422 if (newp && newlen != sizeof(int)) 423 return (EINVAL); 424 *oldlenp = sizeof(int); 425 if (oldp) 426 error = copyout(valp, oldp, sizeof(int)); 427 if (error == 0 && newp) 428 error = copyin(newp, valp, sizeof(int)); 429 return (error); 430 } 431 432 /* 433 * As above, but read-only. 434 */ 435 int 436 sysctl_rdint(oldp, oldlenp, newp, val) 437 void *oldp; 438 size_t *oldlenp; 439 void *newp; 440 int val; 441 { 442 int error = 0; 443 444 if (oldp && *oldlenp < sizeof(int)) 445 return (ENOMEM); 446 if (newp) 447 return (EPERM); 448 *oldlenp = sizeof(int); 449 if (oldp) 450 error = copyout((caddr_t)&val, oldp, sizeof(int)); 451 return (error); 452 } 453 454 /* 455 * Validate parameters and get old / set new parameters 456 * for a string-valued sysctl function. 457 */ 458 int 459 sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) 460 void *oldp; 461 size_t *oldlenp; 462 void *newp; 463 size_t newlen; 464 char *str; 465 int maxlen; 466 { 467 int len, error = 0; 468 469 len = strlen(str) + 1; 470 if (oldp && *oldlenp < len) 471 return (ENOMEM); 472 if (newp && newlen >= maxlen) 473 return (EINVAL); 474 if (oldp) { 475 *oldlenp = len; 476 error = copyout(str, oldp, len); 477 } 478 if (error == 0 && newp) { 479 error = copyin(newp, str, newlen); 480 str[newlen] = 0; 481 } 482 return (error); 483 } 484 485 /* 486 * As above, but read-only. 487 */ 488 int 489 sysctl_rdstring(oldp, oldlenp, newp, str) 490 void *oldp; 491 size_t *oldlenp; 492 void *newp; 493 char *str; 494 { 495 int len, error = 0; 496 497 len = strlen(str) + 1; 498 if (oldp && *oldlenp < len) 499 return (ENOMEM); 500 if (newp) 501 return (EPERM); 502 *oldlenp = len; 503 if (oldp) 504 error = copyout(str, oldp, len); 505 return (error); 506 } 507 508 /* 509 * Validate parameters and get old / set new parameters 510 * for a structure oriented sysctl function. 511 */ 512 int 513 sysctl_struct(oldp, oldlenp, newp, newlen, sp, len) 514 void *oldp; 515 size_t *oldlenp; 516 void *newp; 517 size_t newlen; 518 void *sp; 519 int len; 520 { 521 int error = 0; 522 523 if (oldp && *oldlenp < len) 524 return (ENOMEM); 525 if (newp && newlen > len) 526 return (EINVAL); 527 if (oldp) { 528 *oldlenp = len; 529 error = copyout(sp, oldp, len); 530 } 531 if (error == 0 && newp) 532 error = copyin(newp, sp, len); 533 return (error); 534 } 535 536 /* 537 * Validate parameters and get old parameters 538 * for a structure oriented sysctl function. 539 */ 540 int 541 sysctl_rdstruct(oldp, oldlenp, newp, sp, len) 542 void *oldp; 543 size_t *oldlenp; 544 void *newp, *sp; 545 int len; 546 { 547 int error = 0; 548 549 if (oldp && *oldlenp < len) 550 return (ENOMEM); 551 if (newp) 552 return (EPERM); 553 *oldlenp = len; 554 if (oldp) 555 error = copyout(sp, oldp, len); 556 return (error); 557 } 558 559 /* 560 * Get file structures. 561 */ 562 int 563 sysctl_file(where, sizep) 564 char *where; 565 size_t *sizep; 566 { 567 int buflen, error; 568 struct file *fp; 569 char *start = where; 570 571 buflen = *sizep; 572 if (where == NULL) { 573 /* 574 * overestimate by 10 files 575 */ 576 *sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file); 577 return (0); 578 } 579 580 /* 581 * first copyout filehead 582 */ 583 if (buflen < sizeof(filehead)) { 584 *sizep = 0; 585 return (0); 586 } 587 error = copyout((caddr_t)&filehead, where, sizeof(filehead)); 588 if (error) 589 return (error); 590 buflen -= sizeof(filehead); 591 where += sizeof(filehead); 592 593 /* 594 * followed by an array of file structures 595 */ 596 for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) { 597 if (buflen < sizeof(struct file)) { 598 *sizep = where - start; 599 return (ENOMEM); 600 } 601 error = copyout((caddr_t)fp, where, sizeof (struct file)); 602 if (error) 603 return (error); 604 buflen -= sizeof(struct file); 605 where += sizeof(struct file); 606 } 607 *sizep = where - start; 608 return (0); 609 } 610 611 /* 612 * try over estimating by 5 procs 613 */ 614 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 615 616 int 617 sysctl_doproc(name, namelen, where, sizep) 618 int *name; 619 u_int namelen; 620 char *where; 621 size_t *sizep; 622 { 623 register struct proc *p; 624 register struct kinfo_proc *dp = (struct kinfo_proc *)where; 625 register int needed = 0; 626 int buflen = where != NULL ? *sizep : 0; 627 int doingzomb; 628 struct eproc eproc; 629 int error = 0; 630 631 if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL)) 632 return (EINVAL); 633 p = allproc.lh_first; 634 doingzomb = 0; 635 again: 636 for (; p != 0; p = p->p_list.le_next) { 637 /* 638 * Skip embryonic processes. 639 */ 640 if (p->p_stat == SIDL) 641 continue; 642 /* 643 * TODO - make more efficient (see notes below). 644 * do by session. 645 */ 646 switch (name[0]) { 647 648 case KERN_PROC_PID: 649 /* could do this with just a lookup */ 650 if (p->p_pid != (pid_t)name[1]) 651 continue; 652 break; 653 654 case KERN_PROC_PGRP: 655 /* could do this by traversing pgrp */ 656 if (p->p_pgrp->pg_id != (pid_t)name[1]) 657 continue; 658 break; 659 660 case KERN_PROC_TTY: 661 if ((p->p_flag & P_CONTROLT) == 0 || 662 p->p_session->s_ttyp == NULL || 663 p->p_session->s_ttyp->t_dev != (dev_t)name[1]) 664 continue; 665 break; 666 667 case KERN_PROC_UID: 668 if (p->p_ucred->cr_uid != (uid_t)name[1]) 669 continue; 670 break; 671 672 case KERN_PROC_RUID: 673 if (p->p_cred->p_ruid != (uid_t)name[1]) 674 continue; 675 break; 676 } 677 if (buflen >= sizeof(struct kinfo_proc)) { 678 fill_eproc(p, &eproc); 679 error = copyout((caddr_t)p, &dp->kp_proc, 680 sizeof(struct proc)); 681 if (error) 682 return (error); 683 error = copyout((caddr_t)&eproc, &dp->kp_eproc, 684 sizeof(eproc)); 685 if (error) 686 return (error); 687 dp++; 688 buflen -= sizeof(struct kinfo_proc); 689 } 690 needed += sizeof(struct kinfo_proc); 691 } 692 if (doingzomb == 0) { 693 p = zombproc.lh_first; 694 doingzomb++; 695 goto again; 696 } 697 if (where != NULL) { 698 *sizep = (caddr_t)dp - where; 699 if (needed > *sizep) 700 return (ENOMEM); 701 } else { 702 needed += KERN_PROCSLOP; 703 *sizep = needed; 704 } 705 return (0); 706 } 707 708 /* 709 * Fill in an eproc structure for the specified process. 710 */ 711 void 712 fill_eproc(p, ep) 713 register struct proc *p; 714 register struct eproc *ep; 715 { 716 register struct tty *tp; 717 718 ep->e_paddr = p; 719 ep->e_sess = p->p_pgrp->pg_session; 720 ep->e_pcred = *p->p_cred; 721 ep->e_ucred = *p->p_ucred; 722 if (p->p_stat == SIDL || p->p_stat == SZOMB) { 723 ep->e_vm.vm_rssize = 0; 724 ep->e_vm.vm_tsize = 0; 725 ep->e_vm.vm_dsize = 0; 726 ep->e_vm.vm_ssize = 0; 727 /* ep->e_vm.vm_pmap = XXX; */ 728 } else { 729 register struct vmspace *vm = p->p_vmspace; 730 731 ep->e_vm.vm_rssize = vm_resident_count(vm); 732 ep->e_vm.vm_tsize = vm->vm_tsize; 733 ep->e_vm.vm_dsize = vm->vm_dsize; 734 ep->e_vm.vm_ssize = vm->vm_ssize; 735 } 736 if (p->p_pptr) 737 ep->e_ppid = p->p_pptr->p_pid; 738 else 739 ep->e_ppid = 0; 740 ep->e_pgid = p->p_pgrp->pg_id; 741 ep->e_jobc = p->p_pgrp->pg_jobc; 742 if ((p->p_flag & P_CONTROLT) && 743 (tp = ep->e_sess->s_ttyp)) { 744 ep->e_tdev = tp->t_dev; 745 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 746 ep->e_tsess = tp->t_session; 747 } else 748 ep->e_tdev = NODEV; 749 if (p->p_wmesg) 750 strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN); 751 ep->e_xsize = ep->e_xrssize = 0; 752 ep->e_xccount = ep->e_xswrss = 0; 753 ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0; 754 if (SESS_LEADER(p)) 755 ep->e_flag |= EPROC_SLEADER; 756 strncpy(ep->e_login, ep->e_sess->s_login, MAXLOGNAME); 757 } 758 759