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