|
|
1.1 ! root 1: # ! 2: /* ! 3: ps - show process status - iiasa version (jek) ! 4: originally from harvard and/or CULC ! 5: ! 6: flags are single letters ! 7: multiple flags can occur in one argument ! 8: dashes are optional but are needed to delimit lists of things ! 9: multiple lists are present(???) ! 10: flags that imply other arguments read the following arguments ! 11: until the end of the list or until an argument starts with dash ! 12: certain flags read exactly one argument ! 13: initialization (i flag) should be done for: ! 14: new users, ! 15: new kernel ! 16: parameters here must change to indicate: ! 17: new tty devices, max tty lines, tty letter changes ! 18: max users ! 19: new things to wait for ! 20: this program should be changed if: ! 21: proc structure makes this obsolete ! 22: etc ! 23: recompilation should occur if: ! 24: kernel structures and or paramters (nproc etc.) change ! 25: any above changes of course ! 26: ! 27: flags are: ! 28: a - show all processes that have pgrps except shells ! 29: b - show background (not detached) ! 30: c - show child times instead of process times ! 31: d - show detached processes inherited by init ! 32: e - show the environment with the args ! 33: f - show foreground jobs, connected to tty ! 34: g - show processes in given pgrps ! 35: h - unused ! 36: i - perform initialization (implies 'n') ! 37: j,k - unused ! 38: l - print long format. includes most good stuff ! 39: m - specify different memory file (file is next arg) ! 40: n - show no processes ! 41: o - unused ! 42: p - show only processes whose id's are in list (following args) ! 43: q - unused ! 44: r - repeat indefinitely (number of r's = seconds or r#) ! 45: s - show stopped processes ! 46: t - show only processes associated with ttys in list (following) ! 47: u - show only processes (or ancestors of) for users in list ! 48: v - be verbose - show the most information ! 49: w - wide format, show entire argument list (up to 512 chars) ! 50: x - show unattached processes - no pgrp. a+x gives shells also ! 51: y - unused ! 52: z - show zombies ! 53: A - show ALL information possible ! 54: B - show busy processes ! 55: F - go fast, avoid swap space. ! 56: G - print pgrp ! 57: U - use different UNIX file (next arg) ! 58: S - show size ! 59: T - show tty information ! 60: W - print wait channels in hex ! 61: */ ! 62: ! 63: #include <signal.h> ! 64: #include <h/param.h> ! 65: #include <h/dir.h> ! 66: #include <h/user.h> ! 67: #include <h/proc.h> ! 68: #include <h/pte.h> ! 69: #include <h/vm.h> ! 70: #include <h/inode.h> ! 71: #include <h/file.h> ! 72: #include <h/buf.h> ! 73: #include <h/text.h> ! 74: #include <h/tty.h> ! 75: #include <h/conf.h> ! 76: #include <nlist.h> ! 77: #include <sys/stat.h> ! 78: #include <stdio.h> ! 79: #include <pwd.h> ! 80: ! 81: ! 82: #define TRUE 1 ! 83: #define FALSE 0 ! 84: #define INTPPG (NBPG/sizeof(int)) ! 85: #define MAXARGPG 5 ! 86: ! 87: #define Usrptmap ((struct pte *)info.kaddr[ausrptmap]) ! 88: #define usrpt ((struct pte *)info.kaddr[ausrpt]) ! 89: #define cswitch ((struct cdevsw *)info.kaddr[acdevsw]) ! 90: struct proc *proc, *kproc; ! 91: struct text *text, *ktext; ! 92: struct buf *buf, *swbuf; ! 93: struct inode *inode; ! 94: int nproc, ntext, hz, nbuf, ninode, nfile, nswbuf; ! 95: union { ! 96: struct user user; ! 97: char upages[UPAGES][NBPG]; ! 98: } user; ! 99: int pad1; /* supposedly to aviod hardware problem reading /dev/mem */ ! 100: struct pte pagetable[UPAGES + MAXARGPG]; /* for users page table */ ! 101: int pad2; /* supposedly to aviod hardware problem reading /dev/mem */ ! 102: ! 103: #define u user.user ! 104: #define MSPID 2 /* max system pid, not to considered BUSY */ ! 105: ! 106: #define MAXUSERS 256 /* total different users */ ! 107: #define UNAMELENGTH 8 /* length of a user name */ ! 108: #define NSPEC 15 /* number of specified things (proc, user, tty */ ! 109: #define MAXTTYS 100 ! 110: ! 111: /* definitions to reuse uninteresting proc table entries for linked lists */ ! 112: ! 113: struct procinfo { /* structure to use for */ ! 114: char *pi_cmd; /* attaching a time */ ! 115: struct ttyline *pi_tty; ! 116: long pi_time; /* and an arg string to a proc */ ! 117: }; ! 118: ! 119: #define p_next p_link /* pointer to next proc in global list */ ! 120: #define p_bro p_rlink /* next process with same parent */ ! 121: #define p_son p_xlink /* first child of this process */ ! 122: #define pinfo(p) (*((struct procinfo **)&p->p_sig)) ! 123: #define procsize(p) ((p)->p_tsize + (p)->p_dsize + (p)->p_ssize) ! 124: /* size of process */ ! 125: #define ABS(x) ((int)(x) & ~0x80000000) /* clear top bit - type int */ ! 126: #define K 1024 ! 127: #define KSHIFT 10 ! 128: ! 129: #define msize(x) (x >> (KSHIFT-PGSHIFT)) ! 130: ! 131: #define USERPAGE 0 /* flag for pread - read user page */ ! 132: #define TOPMEM 1 /* flag for pread - read top of mem */ ! 133: ! 134: struct proc *plist; ! 135: int mypid; /* pid of this process */ ! 136: ! 137: char Aflag, aflag, Bflag, bflag, cflag, dflag, eflag, fflag, Fflag; ! 138: char Gflag, iflag, lflag, mflag, nflag, rflag, Sflag, sflag, Tflag; ! 139: char Uflag, uflag, vflag, wflag, xflag, nxflag, Wflag, zflag; ! 140: int select; /* flag indicating process selection */ ! 141: ! 142: int ntotal, nbusy, nloaded, nswapped; ! 143: int ktotal, kbusy, kloaded, kswapped; ! 144: ! 145: /* specified users, ttys, pids, pgrps */ ! 146: union numptr { ! 147: int nm_int; ! 148: char *nm_ptr; ! 149: }; ! 150: ! 151: union ttyptr { ! 152: struct ttyline *ty_line; ! 153: char *ty_ptr; ! 154: }; ! 155: ! 156: union numptr pids[NSPEC], *ppids = pids; /* specified process ids */ ! 157: union numptr grps[NSPEC], *pgrps = grps; /* specified groups */ ! 158: union numptr uids[NSPEC], *puids = uids; /* specified user ids */ ! 159: union ttyptr ttys[NSPEC], *pttys = ttys; /* specified ttys */ ! 160: ! 161: /* files needed by ps */ ! 162: ! 163: char *memf = "/dev/mem"; /* default memory file */ ! 164: int mem; /* memory file descriptor */ ! 165: char *kmemf = "/dev/kmem"; /* virtual memory file */ ! 166: int kmem; /* virtual memory file descriptor */ ! 167: char *symf = "/vmunix"; /* default symbol file */ ! 168: char *swapf = "/dev/swap"; /* default swap file */ ! 169: int swap; /* swap area file descriptor */ ! 170: char *infof = "/etc/spsinfo"; /* default info save file */ ! 171: int infofd; /* info file descriptor */ ! 172: ! 173: /* variables read from the kernel */ ! 174: ! 175: struct nlist namelist[] = { ! 176: #define aproc 0 ! 177: {"_proc"}, ! 178: #define aswapdev 1 ! 179: {"_swapdev"}, ! 180: #define aswplo 2 ! 181: {"_swplo"}, ! 182: #define answbuf 3 ! 183: {"_nswbuf"}, ! 184: #define atext 4 ! 185: {"_text"}, ! 186: #define abuf 5 ! 187: {"_buf"}, ! 188: #define abfreeli 6 ! 189: {"_bfreelist"}, ! 190: #define akl11 7 ! 191: {"_kl11"}, ! 192: #define adh11 8 ! 193: {"_dh11"}, ! 194: #define alpdt 9 ! 195: {"_lp_softc"}, ! 196: #define albolt 10 ! 197: {"_lbolt"}, ! 198: #define atout 11 ! 199: {"_tout"}, ! 200: #define arunin 12 ! 201: {"_runin"}, ! 202: #define arunout 13 ! 203: {"_runout"}, ! 204: #define aipc 14 ! 205: {"_ipc"}, ! 206: #define afile 15 ! 207: {"_file"}, ! 208: #define ainode 16 ! 209: {"_inode"}, ! 210: #define amaplock 17 ! 211: {"_maplock"}, ! 212: #define acoremap 18 ! 213: {"_coremap"}, ! 214: #define aswapmap 19 ! 215: {"_swapmap"}, ! 216: #define au 20 ! 217: {"_u"}, ! 218: #define adz11 21 ! 219: {"_dz_tty"}, ! 220: #define aetext 22 ! 221: {"_etext"}, ! 222: #define ausrptmap 23 ! 223: {"_Usrptmap"}, ! 224: #define ausrpt 24 ! 225: {"_usrpt"}, ! 226: #define achtbuf 25 ! 227: {"_chtbuf"}, ! 228: #define arhtbuf 26 ! 229: {"_rhtbuf"}, ! 230: #define ahpbuf 27 ! 231: {"_hpbuf"}, ! 232: #define aswbuf 28 ! 233: {"_swbuf"}, ! 234: #define arswbuf 29 ! 235: {"_rswbuf"}, ! 236: #define acons 30 ! 237: {"_cons"}, ! 238: #define ark7 31 ! 239: {"_rrk7buf"}, ! 240: #define achrfclist 32 ! 241: {"_Chrfclist"}, ! 242: #define anproc 33 ! 243: {"_nproc"}, ! 244: #define antext 34 ! 245: {"_ntext"}, ! 246: #define anbuf 35 ! 247: {"_nbuf"}, ! 248: #define ahz 36 ! 249: {"_hz"}, ! 250: #define aninode 37 ! 251: {"_ninode"}, ! 252: #define anfile 38 ! 253: {"_nfile"}, ! 254: #define answap 39 ! 255: {"_nswap"}, ! 256: #define acdevsw 40 ! 257: {"_cdevsw"}, ! 258: #define aChconntab 41 ! 259: {"_Chconntab"}, ! 260: #define MAXSYMBOLS 42 ! 261: {"", 0, 0}, ! 262: }; ! 263: ! 264: /* this structure is read from info file or initialized (iflag) */ ! 265: ! 266: struct { ! 267: caddr_t kaddr[MAXSYMBOLS]; /* useful kernel addresses */ ! 268: char unames[MAXUSERS][UNAMELENGTH]; /* user names */ ! 269: struct ttyline { ! 270: struct tty *l_addr; /* address of ttystruct */ ! 271: unsigned l_pgrp; /* process group */ ! 272: char l_name[2]; /* name */ ! 273: dev_t l_dev; /* device number */ ! 274: } ttyline[MAXTTYS]; ! 275: ! 276: } info; ! 277: int swapdev; /* major, minor of swap device */ ! 278: int swplo; /* unix swap disk offset */ ! 279: int nswap; /* unix swap space size */ ! 280: ! 281: struct ttyline notty = {0, 0, {"- "}}; ! 282: ! 283: /* flags for once only activities (once per repeat) */ ! 284: ! 285: int heading; ! 286: int coreinit, core; ! 287: char *topmem; ! 288: int arglength; ! 289: char *getcore(), *store(), *waitingfor(), *getcmd(), *strcat(), *brk(); ! 290: ! 291: main(argc,argv) ! 292: char *argv[]; ! 293: { ! 294: register char *cp, **ap; ! 295: register int i; ! 296: int myuid; ! 297: extern char _sobuf[]; ! 298: ! 299: if ((myuid = getuid()) == 0) ! 300: nice(-100); ! 301: ! 302: setbuf(stdout, _sobuf); ! 303: select = 0; ! 304: for (ap = &argv[1]; --argc; ap++) { ! 305: for (cp = *ap; *cp;) { ! 306: switch (*cp++) { ! 307: case '-': ! 308: continue; ! 309: case 'A': /* EVERYTHING */ ! 310: Aflag++; ! 311: continue; ! 312: case 'a': /* all procs attached to ttys */ ! 313: bflag++; /* include background */ ! 314: fflag++; /* include foreground */ ! 315: dflag++; /* include detached */ ! 316: aflag++; /* include shells */ ! 317: select++; ! 318: continue; ! 319: case 'b': /* all background processes */ ! 320: bflag++; ! 321: select++; ! 322: continue; ! 323: case 'B': /* all busy processes */ ! 324: Bflag++; ! 325: select++; ! 326: lflag++; ! 327: continue; ! 328: case 'c': ! 329: cflag++; ! 330: lflag++; ! 331: continue; ! 332: case 'd': /* detached processes */ ! 333: dflag++; ! 334: select++; ! 335: continue; ! 336: case 'e': ! 337: eflag++; ! 338: continue; ! 339: case 'f': /* foreground only */ ! 340: fflag++; ! 341: select++; ! 342: continue; ! 343: case 'F': /* go fast, don't touch swap */ ! 344: Fflag++; ! 345: continue; ! 346: case 'G': /* print pgrp */ ! 347: Gflag++; ! 348: continue; ! 349: case 'g': /* specify process gourp */ ! 350: select++; ! 351: while (argc > 1) { ! 352: if (**++ap == '-') { ! 353: ap--; ! 354: break; ! 355: } ! 356: --argc; ! 357: if (pgrps >= &grps[NSPEC]) ! 358: prexit("%a: too many groups\n"); ! 359: (pgrps++)->nm_int = atoi(*ap); ! 360: } ! 361: if (pgrps == grps) ! 362: (pgrps++)->nm_int = getpgrp(); ! 363: continue; ! 364: case 'i': /* initialize info file */ ! 365: if (myuid != 0) /* must be super user */ ! 366: goto def; ! 367: iflag++; ! 368: nflag++; ! 369: Uflag++; ! 370: continue; ! 371: case 'l': /* long output */ ! 372: lflag++; ! 373: continue; ! 374: case 'm': /* use designated memory file */ ! 375: if (myuid != 0) /* must be super user */ ! 376: goto def; ! 377: if (argc-- < 2 || **++ap == '-') ! 378: prexit("%a: missing memory file\n"); ! 379: memf = *ap; ! 380: mflag++; ! 381: continue; ! 382: case 'n': ! 383: select++; ! 384: nflag++; ! 385: continue; ! 386: case 'p': /* only designated processes */ ! 387: select++; ! 388: while (argc > 1) { ! 389: if (**++ap == '-') { ! 390: ap--; ! 391: break; ! 392: } ! 393: --argc; ! 394: if (ppids >= &pids[NSPEC]) ! 395: prexit("%a: too many pids\n"); ! 396: (ppids++)->nm_int = atoi(*ap); ! 397: } ! 398: continue; ! 399: case 'r': /* repeat every <number> seconds */ ! 400: if (myuid != 0) ! 401: goto def; ! 402: rflag++; ! 403: for (i = 0; *cp >= '0' && *cp <= '9'; cp++) ! 404: i = i * 10 + *cp - '0'; ! 405: if (i) ! 406: rflag = i; ! 407: continue; ! 408: case 'U': /* use designated symbol file */ ! 409: if (myuid != 0) ! 410: goto def; ! 411: if (argc-- < 2 || **++ap == '-') ! 412: prexit("%a: missing symbol file\n"); ! 413: symf = *ap; ! 414: Uflag++; ! 415: continue; ! 416: case 's': ! 417: sflag++; ! 418: select++; ! 419: continue; ! 420: case 'S': ! 421: Sflag++; ! 422: continue; ! 423: case 'T': ! 424: Tflag++; ! 425: continue; ! 426: case 't': /* on designated tty(s) */ ! 427: select++; ! 428: while (argc > 1) { ! 429: if (**++ap == '-') { ! 430: ap--; ! 431: break; ! 432: } ! 433: --argc; ! 434: if (pttys >= &ttys[NSPEC]) ! 435: prexit("%a: too many ttys\n"); ! 436: (pttys++)->ty_ptr = *ap; ! 437: } ! 438: if (pttys == ttys) { ! 439: char *ttyname(); ! 440: ! 441: if ( (pttys->ty_ptr = ttyname(2)) == 0) ! 442: prexit("%a: unknown tty\n"); ! 443: else if (strcmp("/dev/console", pttys->ty_ptr) == 0) ! 444: (pttys++)->ty_ptr = "co"; ! 445: else ! 446: (pttys++)->ty_ptr += ! 447: sizeof("/dev/tty") - 1; ! 448: } ! 449: continue; ! 450: case 'u': /* specific user name */ ! 451: aflag++; ! 452: select++; ! 453: puids = &uids[0]; ! 454: while (argc > 1) { ! 455: if (**++ap == '-') { ! 456: ap--; ! 457: break; ! 458: } ! 459: --argc; ! 460: if (puids >= &uids[NSPEC]) ! 461: prexit("%a: too many users\n"); ! 462: (puids++)->nm_ptr = *ap; ! 463: } ! 464: if (puids == &uids[0]) ! 465: (puids++)->nm_int = myuid; ! 466: continue; ! 467: case 'v': /* most verbose output */ ! 468: vflag++; ! 469: lflag++; ! 470: continue; ! 471: case 'W': ! 472: Wflag++; ! 473: continue; ! 474: case 'w': /* wide form (all arguments) */ ! 475: wflag++; ! 476: continue; ! 477: case 'x': /* include un-owned procs */ ! 478: xflag++; ! 479: select++; ! 480: continue; ! 481: case 'z': /* include only zombies */ ! 482: zflag++; ! 483: select++; ! 484: continue; ! 485: def: ! 486: default: ! 487: prexit("%a: unknown switch: %c\n", *--cp); ! 488: } ! 489: break; ! 490: } ! 491: } ! 492: ! 493: /* these lengths are kludgely tuned to make things not exceed 79 columns */ ! 494: arglength = 60; ! 495: if (lflag) ! 496: arglength -= 28; ! 497: if (vflag) ! 498: arglength -= 14; ! 499: if ((mem = open(memf, 0)) < 0) ! 500: prexit("%a: cannot read system memory: %s\n", memf); ! 501: if ((kmem = open(kmemf, 0)) < 0) ! 502: prexit("%a: cannot read system virtural memory: %s\n", kmemf); ! 503: if (!Fflag && (swap = open(swapf, 0)) <0) ! 504: prexit("%a: cannot read swap device: %s\n", swapf); ! 505: ! 506: if (!iflag) ! 507: if ((i = open(infof, 0)) < 0) ! 508: prexit("%a: cannot open info file\n"); ! 509: else if (read(i, &info, sizeof info) != sizeof info) ! 510: prexit("%a: cannot read info file\n"); ! 511: else ! 512: close(i); ! 513: if (Uflag) { ! 514: struct nlist *np; ! 515: if ((i = open(symf, 0)) < 0) ! 516: prexit("%a: can't read symbol file\n"); ! 517: close(i); ! 518: nlist(symf, namelist); ! 519: for (np = namelist; np < &namelist[MAXSYMBOLS]; np++) ! 520: if (np->n_value == 0) ! 521: fprintf(stderr, "%a: can't find symbol: %s\n", ! 522: np->n_name); ! 523: if (namelist[0].n_value == -1) ! 524: prexit("%a: cannot read symbol file: %s\n", symf); ! 525: for (i = 0; i < MAXSYMBOLS; i++) ! 526: info.kaddr[i] = (caddr_t)namelist[i].n_value; ! 527: info.kaddr[aetext] = (caddr_t)( ((unsigned)info.kaddr[aetext] + 63) & ~63); ! 528: } ! 529: if (iflag) { ! 530: readusers(); ! 531: ttyinit(); ! 532: if ((infofd = creat(infof, 0600)) < 0) ! 533: prexit("%a: cannot create info file\n"); ! 534: if ((i = write(infofd, &info, sizeof info)) != sizeof info) { ! 535: if (i == -1) ! 536: perror(0); ! 537: prexit("%a: cannot write info file: %d\n", i); ! 538: } ! 539: close(infofd); ! 540: } ! 541: lseek(kmem, (long)info.kaddr[aswapdev], 0); ! 542: read(kmem, &swapdev, sizeof(swapdev) ); ! 543: lseek(kmem, (long)info.kaddr[aswplo], 0); ! 544: read(kmem, &swplo, sizeof(swplo) ); ! 545: lseek(kmem, (long)info.kaddr[answap], 0); ! 546: read(kmem, &nswap, sizeof(nswap) ); ! 547: lseek(kmem, (long)info.kaddr[anproc], 0); ! 548: read(kmem, &nproc, sizeof(nproc) ); ! 549: lseek(kmem, (long)info.kaddr[antext], 0); ! 550: read(kmem, &ntext, sizeof(ntext) ); ! 551: lseek(kmem, (long)info.kaddr[anbuf], 0); ! 552: read(kmem, &nbuf, sizeof(nbuf) ); ! 553: lseek(kmem, (long)info.kaddr[abuf], 0); ! 554: read(kmem, &buf, sizeof(buf) ); ! 555: lseek(kmem, (long)info.kaddr[answbuf], 0); ! 556: read(kmem, &nswbuf, sizeof(nswbuf) ); ! 557: lseek(kmem, (long)info.kaddr[aswbuf], 0); ! 558: read(kmem, &swbuf, sizeof(swbuf) ); ! 559: lseek(kmem, (long)info.kaddr[aninode], 0); ! 560: read(kmem, &ninode, sizeof(ninode) ); ! 561: lseek(kmem, (long)info.kaddr[ainode], 0); ! 562: read(kmem, &inode, sizeof(inode) ); ! 563: lseek(kmem, (long)info.kaddr[ahz], 0); ! 564: read(kmem, &hz, sizeof(hz) ); ! 565: lseek(kmem, (long)info.kaddr[aproc], 0); ! 566: read(kmem, &kproc, sizeof(kproc)); ! 567: lseek(kmem, (long)info.kaddr[atext], 0); ! 568: read(kmem, &ktext, sizeof(ktext)); ! 569: proc = (struct proc *)getcore(nproc * sizeof(struct proc)); ! 570: text = (struct text *)getcore(ntext * sizeof(struct text)); ! 571: if (puids != &uids[0] && uids[0].nm_int != myuid) ! 572: usersetup(); ! 573: if (!select) { ! 574: mypid = getpid(); ! 575: (puids++)->nm_int = myuid; ! 576: nxflag++; ! 577: select++; ! 578: } ! 579: ttysetup(); ! 580: topmem = 0; ! 581: do { ! 582: heading = 0; /* reset heading flag (for repeat) */ ! 583: core = coreinit = 0; /* reset core flag (for repeat) */ ! 584: lseek(kmem, (long)kproc, 0); ! 585: read(kmem, proc, nproc * sizeof(struct proc)); ! 586: lseek(kmem, (long)ktext, 0); ! 587: read(kmem, text, ntext * sizeof(struct text)); ! 588: needed(); ! 589: mktree(); ! 590: action (plist, 0); ! 591: printf("%d processes (%dkb), %d busy (%dkb), %d loaded (%dkb)\n", ! 592: ntotal, (ctob(ktotal) + 1023) / 1024, ! 593: nbusy, (ctob(kbusy) + 1023) / 1024, ! 594: nloaded, (ctob(kloaded) + 1023) / 1024); ! 595: fflush(stdout); ! 596: } while (rflag && sleep(rflag) == 0); ! 597: exit(0); ! 598: } ! 599: ! 600: /* read the passwd file and fill in the user name arrays */ ! 601: readusers() ! 602: { ! 603: register struct passwd *pw; ! 604: struct passwd *getpwent(); ! 605: ! 606: while((pw = getpwent()) != 0) { ! 607: if(info.unames[pw->pw_uid][0] == '\0') ! 608: strcpyn(info.unames[pw->pw_uid], pw->pw_name, UNAMELENGTH); ! 609: } ! 610: endpwent(); ! 611: } ! 612: ! 613: /* check for specified user names */ ! 614: ! 615: usersetup() ! 616: { ! 617: register int i; ! 618: register union numptr *ip; ! 619: ! 620: for (ip = uids; ip < puids; ip++) { ! 621: for (i = 0; i < MAXUSERS; i++) ! 622: if (equalu(ip->nm_ptr, info.unames[i])) ! 623: goto cont2; ! 624: prexit("%a: unknown user: %s\n", ip->nm_ptr); ! 625: cont2: ! 626: ip->nm_int = i; ! 627: } ! 628: } ! 629: ! 630: /* compare a fixed length user name */ ! 631: ! 632: equalu(u1, u2) ! 633: register char *u1, *u2; ! 634: { ! 635: register int i = 0; ! 636: ! 637: while (*u1++ == *u2) ! 638: if (!*u2++ || ++i == UNAMELENGTH) ! 639: return 1; ! 640: return 0; ! 641: } ! 642: ! 643: /* ! 644: * Initialize the tty part of the info structure ! 645: */ ! 646: ttyinit() ! 647: { ! 648: struct direct dir; ! 649: struct stat sbuf; ! 650: int fd; ! 651: register struct ttyline *lp = info.ttyline; ! 652: ! 653: if ((fd = open("/dev", 0)) < 0) ! 654: prexit("%a: can't open /dev\n"); ! 655: chdir("/dev"); ! 656: while (read(fd, (char *)&dir, sizeof(dir)) == sizeof(dir)) { ! 657: if (dir.d_ino == 0 || ! 658: strncmp("tty", dir.d_name, 3) != 0 && ! 659: strcmp("console", dir.d_name) != 0) ! 660: continue; ! 661: if (dir.d_name[sizeof("tty") - 1] == 'C') ! 662: continue; ! 663: if (lp >= &info.ttyline[MAXTTYS]) ! 664: prexit("%a: too many ttys in /dev\n"); ! 665: if (dir.d_name[0] == 'c') { ! 666: lp->l_name[0] = 'c'; ! 667: lp->l_name[1] = 'o'; ! 668: } else { ! 669: lp->l_name[0] = dir.d_name[3]; ! 670: lp->l_name[1] = dir.d_name[4]; ! 671: } ! 672: stat(dir.d_name, &sbuf); ! 673: lp->l_dev = sbuf.st_rdev; ! 674: lseek(kmem, (long)&cswitch[major(sbuf.st_rdev)].d_ttys, 0); ! 675: read(kmem, (char *)&lp->l_addr, sizeof(lp->l_addr)); ! 676: lp->l_addr += minor(sbuf.st_rdev); ! 677: lp++; ! 678: } ! 679: close(fd); ! 680: } ! 681: ttysetup() ! 682: { ! 683: register struct ttyline *lp; ! 684: register char *cp; ! 685: union ttyptr *tp; ! 686: struct tty tty; ! 687: ! 688: for (lp = info.ttyline; lp->l_name[0]; lp++) { ! 689: lseek(kmem, (long)lp->l_addr, 0); ! 690: if (read(kmem, &tty, sizeof tty) != sizeof tty) ! 691: prexit("%a: read error in kmem\n"); ! 692: lp->l_pgrp = tty.t_pgrp; ! 693: if (Tflag) ! 694: printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n", ! 695: lp->l_name, major(lp->l_dev), minor(lp->l_dev), ! 696: ABS(lp->l_addr), tty.t_rawq.c_cc, ! 697: tty.t_canq.c_cc, tty.t_outq.c_cc, ! 698: tty.t_pgrp); ! 699: } ! 700: #ifdef CHAOS ! 701: mkchttys(lp); ! 702: #endif ! 703: /* now fix up specified ttys */ ! 704: ! 705: for (tp = &ttys[0]; tp < pttys; tp++) { ! 706: for (lp = info.ttyline; lp->l_name[0]; lp++) ! 707: if (strcmpn(tp->ty_ptr, lp->l_name, 2) == 0) { ! 708: tp->ty_line = lp; ! 709: goto cont2; ! 710: } ! 711: prexit("%a: unknown tty name: %c\n", tp->ty_ptr); ! 712: cont2:; ! 713: } ! 714: } ! 715: ! 716: /* ! 717: * Determine which procs are needed for the printout ! 718: * and add these to a list of needed processes (plist) ! 719: */ ! 720: needed() ! 721: { ! 722: register struct proc *p, *pp; ! 723: register struct text *tp; ! 724: struct ttyline *lp; ! 725: int ok; ! 726: ! 727: plist = 0; ! 728: nswapped = ntotal = nbusy = nloaded = 0; ! 729: kswapped = ktotal = kbusy = kloaded = 0; ! 730: ! 731: for (tp = text; tp < text + ntext; tp++) ! 732: if (tp->x_count) { ! 733: ktotal += tp->x_size; ! 734: if (!(tp->x_ccount)) ! 735: kswapped += tp->x_size; ! 736: } ! 737: ! 738: for (p = proc; p < proc + nproc; p++) { ! 739: if (!p->p_stat) ! 740: continue; ! 741: if (p->p_textp) ! 742: p->p_textp = &text[p->p_textp - ktext]; ! 743: if (p->p_pptr) { ! 744: p->p_pptr = &proc[p->p_pptr - kproc]; ! 745: if (p->p_pptr < proc || p->p_pptr >= &proc[nproc]) { ! 746: fprintf(stderr, "proc %d bad pptr\n", p->p_pid); ! 747: p->p_pptr = proc; ! 748: } ! 749: } else ! 750: p->p_pptr = proc; ! 751: } ! 752: for (p = &proc[0]; p < &proc[nproc]; p++) { ! 753: if (!p->p_stat) ! 754: continue; ! 755: ntotal++; ! 756: ktotal += procsize(p); ! 757: if (p->p_flag != SZOMB) ! 758: if (p->p_flag & SLOAD) { ! 759: nloaded++; ! 760: kloaded += procsize(p); ! 761: if ((tp = p->p_textp) && tp->x_count) { ! 762: tp->x_count = 0; ! 763: kloaded += tp->x_size; ! 764: } ! 765: } else { ! 766: nswapped++; ! 767: kswapped += procsize(p); ! 768: } ! 769: ok = FALSE; ! 770: if (p->p_stat == SRUN || ! 771: p->p_stat == SSLEEP && (p->p_pri < PZERO && p->p_pid > MSPID)) { ! 772: nbusy++; ! 773: kbusy += procsize(p); ! 774: if ((tp = p->p_textp) && tp->x_ccount) { ! 775: tp->x_ccount = 0; ! 776: kbusy += tp->x_size; ! 777: } ! 778: if (Bflag) ! 779: ok = TRUE; ! 780: } ! 781: if (nflag) ! 782: continue; ! 783: if (zflag && p->p_stat == SZOMB) ! 784: ok = TRUE; ! 785: if (sflag && p->p_stat == SSTOP) ! 786: ok = TRUE; ! 787: if (select == 0 && mypid && p->p_pid == mypid) ! 788: continue; ! 789: if (p->p_pgrp == 0) ! 790: if (xflag) ! 791: ok = TRUE; ! 792: else if (nxflag) ! 793: continue; ! 794: if (dflag && p->p_pgrp != 0 && (p->p_flag & SDETACH) != 0) ! 795: ok = TRUE; ! 796: if (aflag && xflag && p->p_pgrp != 0 && (p->p_flag & SDETACH) == 0 && ! 797: p->p_pptr == &proc[1]) ! 798: ok = TRUE; ! 799: if (puids != uids) { ! 800: register union numptr *ip; ! 801: ! 802: for (pp = p; pp > &proc[1]; pp = pp->p_pptr) ! 803: for (ip = uids; ip < puids; ip++) ! 804: if ((pp->p_uid & 0377) == ip->nm_int){ ! 805: ok = TRUE; ! 806: goto uidok; ! 807: } ! 808: } ! 809: uidok: ! 810: if (pgrps != grps) { ! 811: register union numptr *ip; ! 812: ! 813: for (pp = p; pp > &proc[1]; pp = pp->p_pptr) ! 814: for (ip = grps; ip < pgrps; ip++) ! 815: if (pp->p_pgrp == ip->nm_int) { ! 816: ok = TRUE; ! 817: goto pgrpok; ! 818: } ! 819: } ! 820: pgrpok: ! 821: if (ppids != pids) { ! 822: register union numptr *ip; ! 823: ! 824: for (ip = pids; ip < ppids; ip++) ! 825: if (ip->nm_int == p->p_pid) { ! 826: ok = TRUE; ! 827: goto procok; ! 828: } ! 829: } ! 830: procok: ! 831: if (select && pttys == ttys && !fflag && !bflag && !ok) ! 832: continue; ! 833: if (getu(p) == 0) { ! 834: static struct procinfo fakep = {"--no upage--", ¬ty, 0}; ! 835: ! 836: if (select && !ok) ! 837: continue; ! 838: pinfo(p) = &fakep; ! 839: goto putonlist; ! 840: } ! 841: if (pttys != ttys && p->p_pgrp != 0) { ! 842: union ttyptr *ip; ! 843: ! 844: for (ip = ttys; ip < pttys; ip++) ! 845: if (p->p_pgrp && p->p_pgrp == ip->ty_line->l_pgrp || ! 846: p->p_stat == SSLEEP && ! 847: p->p_wchan >= (char *)ip->ty_line->l_addr && ! 848: p->p_wchan < (char *)ip->ty_line->l_addr + ! 849: sizeof (struct tty) || ! 850: u.u_ttyd == ip->ty_line->l_dev) { ! 851: ok = TRUE; ! 852: break; ! 853: } ! 854: } ! 855: if (p->p_pgrp == 0) ! 856: lp = ¬ty; ! 857: else { ! 858: for (lp = info.ttyline; lp->l_name[0] != 0; lp++) ! 859: if (lp->l_dev == u.u_ttyd) ! 860: break; ! 861: if (lp->l_name[0] == 0) ! 862: lp = ¬ty; ! 863: else if (p->p_pptr != &proc[1]) { ! 864: if (fflag && p->p_pgrp == lp->l_pgrp) ! 865: ok = TRUE; ! 866: if (bflag && p->p_pgrp != lp->l_pgrp && ! 867: (p->p_flag & SDETACH) == 0 && ! 868: p->p_stat != SSTOP) ! 869: ok = TRUE; ! 870: } ! 871: } ! 872: if (select && !ok) ! 873: continue; ! 874: pinfo(p) = (struct procinfo *)getcore(sizeof (struct procinfo)); ! 875: pinfo(p)->pi_time = u.u_vm.vm_utime + u.u_vm.vm_stime; ! 876: pinfo(p)->pi_tty = lp; ! 877: pinfo(p)->pi_cmd = getcmd(p); ! 878: putonlist: ! 879: /* we have a needed proc! */ ! 880: ! 881: p->p_next = plist; ! 882: plist = p; ! 883: p->p_son = p->p_bro = 0; ! 884: } ! 885: } ! 886: /* ! 887: * mktree - sort the needed processes by subtree and at the top by user ! 888: */ ! 889: mktree() ! 890: { ! 891: register struct proc *p, *pp, *lp; ! 892: struct proc *op; ! 893: struct proc proot; ! 894: ! 895: proot.p_bro = 0; ! 896: ! 897: for (p = plist; p; p = p->p_next) { /* for all needed processes */ ! 898: if (p->p_pptr > &proc[1]) { ! 899: for (pp = plist; pp; pp = pp->p_next) ! 900: if (pp == p->p_pptr) { /* if my parent */ ! 901: if (lp = pp->p_son) { /* if siblings */ ! 902: for (op = 0; lp && lp->p_pid < ! 903: p->p_pid; ! 904: lp = (op = lp)->p_bro) ! 905: ; ! 906: if (op) { ! 907: p->p_bro = lp; ! 908: op->p_bro = p; ! 909: break; ! 910: } ! 911: } ! 912: p->p_bro = lp; /* here if first or only */ ! 913: pp->p_son = p; ! 914: break; ! 915: } ! 916: if (pp) /* if we found the parent */ ! 917: continue; ! 918: } ! 919: ! 920: /* we have a top level process, sort into top level list */ ! 921: ! 922: for (pp = (lp = &proot)->p_bro; pp; pp = (lp = pp)->p_bro) ! 923: if ((p->p_uid & 0377) < (pp->p_uid & 0377) || ! 924: (p->p_uid & 0377) == (pp->p_uid & 0377) && ! 925: p->p_pid < pp->p_pid) ! 926: break; ! 927: p->p_bro = lp->p_bro; ! 928: lp->p_bro = p; ! 929: } ! 930: plist = proot.p_bro; ! 931: } ! 932: ! 933: action(p, md) ! 934: register struct proc *p; ! 935: register int md; ! 936: { ! 937: ! 938: if (p) { ! 939: printp(p, md); ! 940: if (p->p_son) ! 941: action(p->p_son, md+1); ! 942: if (p->p_bro) ! 943: action(p->p_bro, md); ! 944: } ! 945: } ! 946: ! 947: /* ! 948: * Pretty print the output according to the switches. ! 949: */ ! 950: printp(p, md) ! 951: register struct proc *p; ! 952: { ! 953: register char *cp, *cp1; ! 954: char stat[10]; ! 955: static int lastuid; ! 956: static char *statnames[] = {"Unk ", "Wait", "Wait", "Run ", ! 957: "Init", "Exit", "Stop"}; ! 958: ! 959: if (!heading) { ! 960: heading++; ! 961: printf("Ty User "); ! 962: if (lflag) { ! 963: printf("Stat"); ! 964: if (vflag) printf(" Flgs Nice Pri "); ! 965: else printf(" "); ! 966: printf("Memory-kb Time Wait? "); ! 967: } ! 968: if (Aflag) ! 969: printf("Address Proc. Clock Alarm "); ! 970: if (Sflag) ! 971: printf("Size "); ! 972: if (Gflag) ! 973: printf("Group "); ! 974: printf("Proc# Command\n"); ! 975: } ! 976: printf("%.2s%c", pinfo(p)->pi_tty->l_name, ! 977: p->p_pgrp == 0 ? ' ' : ! 978: p->p_flag & SDETACH ? '_' : ! 979: p->p_pgrp == pinfo(p)->pi_tty->l_pgrp ? '.' : ! 980: ' '); ! 981: ! 982: if (md == 0) { ! 983: lastuid = p->p_uid & 0377; ! 984: cp = info.unames[lastuid]; ! 985: if (*cp) ! 986: printf("%-8.8s ", cp); ! 987: else ! 988: printf("user%-4.4d ", lastuid); ! 989: } else { ! 990: if (md > 8) ! 991: md = 8; ! 992: printf("%*s*", md, ""); ! 993: if ((p->p_uid & 0377) != lastuid) { /* setuid process! */ ! 994: lastuid = p->p_uid & 0377; ! 995: cp = info.unames[lastuid]; ! 996: } else ! 997: cp = ""; ! 998: md = 8 - md; ! 999: printf("%-*.*s", md, md, cp); ! 1000: } ! 1001: if (lflag) { ! 1002: cp = statnames[p->p_stat]; ! 1003: if (p->p_flag&SLOAD) { ! 1004: for (cp1 = stat; *cp1 = *cp; cp1++, cp++) ! 1005: if (*cp >= 'a' && *cp <= 'z') ! 1006: *cp1 -= 'a' - 'A'; ! 1007: cp = stat; ! 1008: } ! 1009: printf("%-4.4s ", cp); ! 1010: if (vflag) { ! 1011: cp = stat; ! 1012: if (p->p_flag & SSYS) *cp++ = 'U'; ! 1013: if (p->p_flag&SLOCK) *cp++ = 'L'; ! 1014: if (p->p_flag&STRC) *cp++ = 'T'; ! 1015: if (p->p_flag&SWTED) *cp++ = 'W'; ! 1016: if (p->p_flag&SSWAP) *cp++ = 'S'; ! 1017: while(cp < &stat[5]) *cp++ = ' '; ! 1018: *cp = 0; ! 1019: printf("%-4.4s ",stat); ! 1020: if (p->p_nice != NZERO) ! 1021: printf("%4d", p->p_nice - NZERO); ! 1022: else ! 1023: printf(" "); ! 1024: if (p->p_stat != SZOMB) ! 1025: printf("%4d ", p->p_pri); ! 1026: else ! 1027: printf(" "); ! 1028: } ! 1029: if (p->p_stat != SZOMB) { ! 1030: printf("%4d", msize(procsize(p)) ); ! 1031: if (p->p_textp) ! 1032: printf("+%4d ", msize(p->p_textp->x_size)); ! 1033: else ! 1034: printf(" "); ! 1035: prcpu(pinfo(p)->pi_time); ! 1036: } else ! 1037: printf(" "); ! 1038: if (p->p_stat != SZOMB && p->p_stat != SRUN && p->p_stat != SSTOP) ! 1039: if (!Wflag && (cp = waitingfor(p))) ! 1040: printf("%-6.6s ", cp); ! 1041: else printf("%6x ", ABS((int)p->p_wchan)); ! 1042: else printf(" "); ! 1043: } ! 1044: if (Aflag) ! 1045: printf("%6x %6x %6d%6d ", p->p_addr, ! 1046: (p - proc) * sizeof (struct proc) + info.kaddr[aproc], ! 1047: p->p_time, p->p_clktim); ! 1048: if (Sflag) ! 1049: printf("%5x ", procsize(p) ); ! 1050: if (Gflag) ! 1051: printf("%5D ", p->p_pgrp); ! 1052: printf("%5D ", p->p_pid); ! 1053: if (wflag) ! 1054: printf("%s\n", pinfo(p)->pi_cmd); ! 1055: else ! 1056: printf("%-.*s\n", arglength, pinfo(p)->pi_cmd); ! 1057: } ! 1058: ! 1059: /* print cpu time */ ! 1060: ! 1061: prcpu(time) ! 1062: long time; ! 1063: { ! 1064: register unsigned i; ! 1065: ! 1066: if (time < 0) ! 1067: printf(" ---- "); ! 1068: else if (time < (long)hz * 60 * 10) /* less than 10 minutes */ ! 1069: printf("%3d.%1d ", ! 1070: (int)(time / hz), ! 1071: (int)(time % hz / (hz / 10))); ! 1072: else if (time < (long)hz * 60 * 60 * 10)/* less than 10 hours */ ! 1073: printf("%3d M ", ! 1074: (int)((time + (hz * 60) / 2) / (hz * 60))); ! 1075: else { ! 1076: i = (time + ((long)hz * 60 * 60) / 2) / ! 1077: ((long)hz * 60 * 60); ! 1078: if (i < 1000) ! 1079: printf("%3d H ", i); ! 1080: else ! 1081: printf(" ---- "); ! 1082: } ! 1083: } ! 1084: /* Determine what a process is waiting for and describe it. */ ! 1085: ! 1086: char * ! 1087: waitingfor(p) ! 1088: register struct proc *p; ! 1089: { ! 1090: register caddr_t w; ! 1091: register struct ttyline *lp; ! 1092: register char *cp; ! 1093: ! 1094: w = p->p_wchan; ! 1095: if (w == (caddr_t)0) ! 1096: return "null"; ! 1097: if (w >= (char *)kproc && w < (char *)(kproc + nproc)) ! 1098: return "child"; ! 1099: if (w >= (char *)swbuf && w < (char *)(swbuf + nswbuf)) ! 1100: return "swap"; ! 1101: if (w == info.kaddr[arswbuf]) ! 1102: return "rswap"; ! 1103: if (w >= (char *)buf && w < (char *)(buf + nbuf)) ! 1104: return "diskio"; ! 1105: if (w >= info.kaddr[afile] && w < info.kaddr[afile] + sizeof(struct file) * nfile) ! 1106: return "file"; ! 1107: if (w >= (char *)inode && w < (char *)(inode + ninode)) ! 1108: switch((w - (char *)inode) % sizeof(struct inode)) { ! 1109: case 1: ! 1110: return "wpipe"; ! 1111: case 2: ! 1112: return "rpipe"; ! 1113: case 3: ! 1114: return "mutex"; ! 1115: case (int)&((struct inode *)0)->i_un.i_group.g_datq: ! 1116: return "rmux"; ! 1117: default: ! 1118: return "inode"; ! 1119: } ! 1120: if (w == info.kaddr[achtbuf]) ! 1121: return "tapecn"; ! 1122: if (w == info.kaddr[ahpbuf]) ! 1123: return "rpdisk"; ! 1124: if (w == info.kaddr[ark7]) ! 1125: return "rkdisk"; ! 1126: if (w == info.kaddr[arhtbuf]) ! 1127: return "tapeio"; ! 1128: if (w == info.kaddr[alpdt]) ! 1129: return "printr"; ! 1130: if (w == info.kaddr[albolt]) ! 1131: return "lbolt"; ! 1132: if (w == info.kaddr[arunin]) ! 1133: return "runin"; ! 1134: if (w == info.kaddr[arunout]) ! 1135: return "runout"; ! 1136: if (w == info.kaddr[atout]) ! 1137: return "sleep"; ! 1138: if (w == info.kaddr[aipc]) ! 1139: return "ptrace"; ! 1140: if (w == info.kaddr[abfreeli]) ! 1141: return "buffer"; ! 1142: if (w == info.kaddr[amaplock]) ! 1143: return "ubmap"; ! 1144: if (w == info.kaddr[au]) ! 1145: return "pause"; ! 1146: if (w == info.kaddr[achrfclist]) ! 1147: return "chrfc"; ! 1148: for (lp = info.ttyline; lp->l_name[0]; lp++) ! 1149: if (w >= (char *)lp->l_addr && w < (char *)lp->l_addr + sizeof (struct tty)) { ! 1150: #define TTY0 ((struct tty *)0) ! 1151: switch(w - (char *)lp->l_addr) { ! 1152: case (int)&TTY0->t_rawq: ! 1153: cp = "rtty??"; ! 1154: break; ! 1155: case (int)&TTY0->t_outq: ! 1156: cp = "wtty??"; ! 1157: break; ! 1158: case (int)&TTY0->t_state: ! 1159: cp = "otty??"; ! 1160: break; ! 1161: default: ! 1162: cp = "?tty??"; ! 1163: } ! 1164: cp[4] = lp->l_name[0]; ! 1165: cp[5] = lp->l_name[1]; ! 1166: return cp; ! 1167: } ! 1168: return 0; ! 1169: } ! 1170: ! 1171: getu(mproc) ! 1172: register struct proc *mproc; ! 1173: { ! 1174: struct pte *pteaddr, apte; ! 1175: register int i; ! 1176: int ncl, size; ! 1177: ! 1178: size = Sflag ? ctob(UPAGES) : sizeof (struct user); ! 1179: if ((mproc->p_flag & SLOAD) == 0) { ! 1180: lseek(swap, (long)ctob(mproc->p_swaddr), 0); ! 1181: if (read(swap, (char *)&user.user, size) != size) { ! 1182: fprintf(stderr, "%a: cant read u for pid %d from %s\n", ! 1183: mproc->p_pid, swapf); ! 1184: return (0); ! 1185: } ! 1186: return (1); ! 1187: } ! 1188: pteaddr = &Usrptmap[btokmx(mproc->p_p0br) + mproc->p_szpt - 1]; ! 1189: lseek(kmem, (long)(mflag ? ABS(pteaddr) : (int)pteaddr), 0); ! 1190: if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) { ! 1191: printf("%a: cant read indir pte to get u for pid %d from %s\n", ! 1192: mproc->p_pid, swapf); ! 1193: return (0); ! 1194: } ! 1195: lseek(mem, (long) ! 1196: (ctob(apte.pg_pfnum+1) - (UPAGES+MAXARGPG) * sizeof (struct pte)), ! 1197: 0); ! 1198: if (read(mem, (char *)pagetable, sizeof(pagetable)) != sizeof(pagetable)) { ! 1199: printf("%a: cant read page table for u of pid %d from %s\n", ! 1200: mproc->p_pid, swapf); ! 1201: return (0); ! 1202: } ! 1203: ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE); ! 1204: while (--ncl >= 0) { ! 1205: i = ncl * CLSIZE; ! 1206: lseek(mem, (long)ctob(pagetable[MAXARGPG+i].pg_pfnum), 0); ! 1207: if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) { ! 1208: printf("%a: cant read page %d of u of pid %d from %s\n", ! 1209: pagetable[MAXARGPG+i].pg_pfnum, mproc->p_pid, memf); ! 1210: return(0); ! 1211: } ! 1212: } ! 1213: return (1); ! 1214: } ! 1215: char * ! 1216: getcmd(p) ! 1217: register struct proc *p; ! 1218: { ! 1219: struct pte apte; ! 1220: char argbuf[MAXARGPG * NBPG], *argptr; ! 1221: register int *ip; ! 1222: register char *cp, *cp1; ! 1223: int cc, nbad, i; ! 1224: ! 1225: if (p->p_stat == SZOMB) ! 1226: return "--Defunct--"; ! 1227: if ((p->p_flag&SLOAD) == 0 && Fflag) ! 1228: return "--Swapped--"; ! 1229: if (p->p_flag & SSYS) ! 1230: return p->p_pid == 0 ? "UNIX Swapper" : ! 1231: p->p_pid == 2 ? "UNIX Pager" : "UNIX"; ! 1232: for (i = 0; i < MAXARGPG; i++) { ! 1233: argptr = &argbuf[(MAXARGPG - 1 - i) * NBPG]; ! 1234: apte = pagetable[MAXARGPG - 1 - i]; ! 1235: if ((p->p_flag & SLOAD) && apte.pg_fod == 0 && apte.pg_pfnum ) { ! 1236: lseek(mem, (long)ctob(apte.pg_pfnum), 0); ! 1237: if (read(mem, argptr, NBPG) != NBPG) ! 1238: return "---Mem read error (args)---"; ! 1239: } else if (Fflag) ! 1240: goto cheap; ! 1241: else { ! 1242: lseek(swap, (long)ctob(u.u_smap.dm_map[0] + DMMIN - 1 - i), 0); ! 1243: if (read(swap, argptr, NBPG) != NBPG) ! 1244: return "---Swap read error (args)---"; ! 1245: } ! 1246: /* Here block of stack is at argptr */ ! 1247: ip = (int *)&argptr[NBPG]; ! 1248: if (i == 0) { ! 1249: *--ip = 0; ! 1250: ip--; ! 1251: } ! 1252: while (ip > (int *)argptr && *--ip != 0) ! 1253: ; ! 1254: if (ip > (int *)argptr || *ip == 0) ! 1255: break; ! 1256: } ! 1257: if (i >= MAXARGPG) { ! 1258: cheap: ! 1259: argbuf[0] = '('; ! 1260: strncpy(&argbuf[1], u.u_comm, sizeof(u.u_comm)); ! 1261: strcat(argbuf, ")"); ! 1262: return store(argbuf); ! 1263: } ! 1264: cp = (char *)(ip + 1); ! 1265: if (*cp == '\0') ! 1266: cp++; ! 1267: nbad = 0; ! 1268: for (cp1 = cp; cp1 < &argbuf[MAXARGPG*NBPG]; cp1++) { ! 1269: cc = *cp1 & 0177; ! 1270: if (cc == 0) ! 1271: *cp1 = ' '; ! 1272: else if (cc < ' ' || cc == 0177) { ! 1273: if (++nbad >= 5) { ! 1274: *cp1++ = ' '; ! 1275: break; ! 1276: } ! 1277: *cp1 = '?'; ! 1278: } else if (!eflag && cc == '=') { ! 1279: *cp1 = 0; ! 1280: while (cp1 > cp && *--cp1 != ' ') ! 1281: *cp1 = 0; ! 1282: break; ! 1283: } ! 1284: } ! 1285: while (*--cp1 == ' ') ! 1286: *cp1 = 0; ! 1287: if (!wflag && &cp[arglength] < (char *)&argbuf[MAXARGPG*NBPG - 1]) ! 1288: cp[arglength] = 0; ! 1289: return store(cp); ! 1290: } ! 1291: ! 1292: /* ! 1293: * Store a string in core for later use. ! 1294: */ ! 1295: char * ! 1296: store(cp) ! 1297: char *cp; ! 1298: { ! 1299: register char *src, *dst, *svdst; ! 1300: ! 1301: src = cp; ! 1302: while (*src++); ! 1303: svdst = getcore(src - cp); ! 1304: dst = svdst; ! 1305: src = cp; ! 1306: while (*dst++ = *src++); ! 1307: return(svdst); ! 1308: } ! 1309: ! 1310: /* ! 1311: * Allocate and return a pointer to the asked for amount of core ! 1312: */ ! 1313: char * ! 1314: getcore(cnt) ! 1315: register int cnt; ! 1316: { ! 1317: static char *corep; ! 1318: register char *ip; ! 1319: register int incr; ! 1320: char *sbrk(); ! 1321: ! 1322: if (cnt > core) { ! 1323: if (coreinit == 0) { ! 1324: coreinit++; ! 1325: if (topmem) ! 1326: brk(topmem); /* after repeat!! */ ! 1327: else ! 1328: topmem = sbrk(0); ! 1329: corep = topmem; ! 1330: } ! 1331: incr = cnt > 4096 ? cnt : 4096; ! 1332: if (sbrk(incr) == 0) ! 1333: prexit("%a: out of memory!\n"); ! 1334: core += incr; ! 1335: } ! 1336: ip = corep; ! 1337: core -= cnt; ! 1338: corep += cnt; ! 1339: return(ip); ! 1340: } ! 1341: #ifdef CHAOS ! 1342: #include "chunix/chsys.h" ! 1343: #include <chaos/chaos.h> ! 1344: ! 1345: mkchttys(lp) ! 1346: register struct ttyline *lp; ! 1347: { ! 1348: register struct connection **cnp; ! 1349: register int i; ! 1350: struct tty tty; ! 1351: struct connection *Chconntab[CHNCONNS]; ! 1352: struct connection conn; ! 1353: ! 1354: lseek(kmem, (long)info.kaddr[aChconntab], 0); ! 1355: read(kmem, (char *)Chconntab, sizeof(Chconntab)); ! 1356: for (i = 0, cnp = Chconntab; cnp < &Chconntab[CHNCONNS]; i++, cnp++) { ! 1357: if (!*cnp) ! 1358: continue; ! 1359: lseek(kmem, (long)*cnp, 0); ! 1360: read(kmem, (char *)&conn, sizeof(conn)); ! 1361: if ((conn.cn_flags & CHTTY) == 0) ! 1362: continue; ! 1363: lseek(kmem, (long)conn.cn_ttyp, 0); ! 1364: read(kmem, (char *)&tty, sizeof(tty)); ! 1365: if (lp >= &info.ttyline[MAXTTYS]) ! 1366: prexit("%a: too many ttys\n"); ! 1367: lp->l_addr = conn.cn_ttyp; ! 1368: lp->l_pgrp = tty.t_pgrp; ! 1369: lp->l_dev = tty.t_dev; ! 1370: lp->l_name[0] = 'C'; ! 1371: lp->l_name[1] = i < 10 ? '0' + i : ! 1372: i - 10 <= 'z' - 'a' ? i - 10 + 'a' : ! 1373: i - 10 - ('z' - 'a') + 'A'; ! 1374: if (Tflag) ! 1375: printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n", ! 1376: lp->l_name, major(lp->l_dev), minor(lp->l_dev), ! 1377: ABS(lp->l_addr), tty.t_rawq.c_cc, ! 1378: tty.t_canq.c_cc, tty.t_outq.c_cc, ! 1379: tty.t_pgrp); ! 1380: lp++; ! 1381: } ! 1382: } ! 1383: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.