|
|
1.1 ! root 1: static char *sccsid = "@(#)w.c 4.4 (Berkeley) 6/5/81"; ! 2: /* ! 3: * w - print system status (who and what) ! 4: * ! 5: * This program is similar to the systat command on Tenex/Tops 10/20 ! 6: * It needs read permission on /dev/mem, /dev/kmem, and /dev/drum. ! 7: */ ! 8: #include <sys/param.h> ! 9: #include <nlist.h> ! 10: #include <stdio.h> ! 11: #include <ctype.h> ! 12: #include <utmp.h> ! 13: #include <time.h> ! 14: #include <sys/stat.h> ! 15: #include <sys/dir.h> ! 16: #include <sys/user.h> ! 17: #include <sys/proc.h> ! 18: #include <machine/pte.h> ! 19: #include <sys/vm.h> ! 20: ! 21: #define NMAX sizeof(utmp.ut_name) ! 22: #define LMAX sizeof(utmp.ut_line) ! 23: ! 24: #define ARGWIDTH 24 /* # chars left on 80 col crt for args */ ! 25: ! 26: struct pr { ! 27: short w_pid; /* proc.p_pid */ ! 28: char w_flag; /* proc.p_flag */ ! 29: short w_size; /* proc.p_size */ ! 30: float w_pctcpu; /* proc.p_pctcpu */ ! 31: long w_ptime; /* proc.p_time */ ! 32: long w_rss; /* proc.p_rssize */ ! 33: long w_seekaddr; /* where to find args */ ! 34: long w_lastpg; /* disk address of stack */ ! 35: int w_igintr; /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */ ! 36: time_t w_time; /* CPU time used by this process */ ! 37: time_t w_ctime; /* CPU time used by children */ ! 38: ino_t w_tty; /* tty inode of process */ ! 39: char w_comm[15]; /* user.u_comm, null terminated */ ! 40: char w_args[ARGWIDTH+1]; /* args if interesting process */ ! 41: } *pr; ! 42: ! 43: struct find { ! 44: struct find *f_parent; /* parent pointer */ ! 45: ino_t f_tty; /* tty for this process */ ! 46: struct pr *f_pr; /* pointer to pr */ ! 47: } *f; ! 48: ! 49: ! 50: int nproc; ! 51: ! 52: struct nlist nl[] = { ! 53: { "_proc" }, ! 54: #define X_PROC 0 ! 55: { "_swapdev" }, ! 56: #define X_SWAPDEV 1 ! 57: { "_Usrptmap" }, ! 58: #define X_USRPTMA 2 ! 59: { "_usrpt" }, ! 60: #define X_USRPT 3 ! 61: { "_nswap" }, ! 62: #define X_NSWAP 4 ! 63: { "_avenrun" }, ! 64: #define X_AVENRUN 5 ! 65: { "_bootime" }, ! 66: #define X_BOOTIME 6 ! 67: { "_ecmx" }, ! 68: #define X_ECMX 7 ! 69: { "_nproc" }, ! 70: #define X_NPROC 8 ! 71: { 0 }, ! 72: }; ! 73: ! 74: FILE *ps; ! 75: FILE *ut; ! 76: FILE *bootfd; ! 77: int kmem; ! 78: int mem; ! 79: int swap; /* /dev/kmem, mem, and swap */ ! 80: int nswap; ! 81: int ecmx; ! 82: ino_t tty; ! 83: char doing[520]; /* process attached to terminal */ ! 84: float avenrun[3]; ! 85: struct proc *aproc; ! 86: ! 87: #define DIV60(t) ((t+30)/60) /* x/60 rounded */ ! 88: #define TTYEQ (tty == pr[i].w_tty) ! 89: #define IGINT (1+3*1) /* ignoring both SIGINT & SIGQUIT */ ! 90: ! 91: char *getargs(); ! 92: char *fread(); ! 93: char *ctime(); ! 94: char *strrchr(); ! 95: FILE *popen(); ! 96: struct tm *localtime(); ! 97: ! 98: int debug; /* true if -d flag: debugging output */ ! 99: int header = 1; /* true if -h flag: don't print heading */ ! 100: int lflag = 1; /* true if -l flag: long style output */ ! 101: int login; /* true if invoked as login shell */ ! 102: int idle; /* number of minutes user is idle */ ! 103: int nusers; /* number of users logged in now */ ! 104: char * sel_user; /* login of particular user selected */ ! 105: char firstchar; /* first char of name of prog invoked as */ ! 106: time_t jobtime; /* total cpu time visible */ ! 107: double percentcpu; /* percentage of cpu */ ! 108: int pagesused; /* total number of pages */ ! 109: int pagesresident; /* pages in memory */ ! 110: time_t now; /* the current time of day */ ! 111: struct tm *nowt; /* current time as time struct */ ! 112: time_t bootime, uptime; /* time of last reboot & elapsed time since */ ! 113: int np; /* number of processes currently active */ ! 114: struct utmp utmp; ! 115: struct proc mproc; ! 116: struct user up; ! 117: char fill[512]; ! 118: ! 119: main(argc, argv) ! 120: char **argv; ! 121: { ! 122: int days, hrs, mins; ! 123: register int i, j; ! 124: char *cp; ! 125: register int curpid, empty; ! 126: char obuf[BUFSIZ]; ! 127: ! 128: setbuf(stdout, obuf); ! 129: login = (argv[0][0] == '-'); ! 130: cp = strrchr(argv[0], '/'); ! 131: firstchar = login ? argv[0][1] : (cp==0) ? argv[0][0] : cp[1]; ! 132: cp = argv[0]; /* for Usage */ ! 133: ! 134: while (argc > 1) { ! 135: if (argv[1][0] == '-') { ! 136: for (i=1; argv[1][i]; i++) { ! 137: switch(argv[1][i]) { ! 138: ! 139: case 'd': ! 140: debug++; ! 141: break; ! 142: ! 143: case 'h': ! 144: header = 0; ! 145: break; ! 146: ! 147: case 'l': ! 148: lflag++; ! 149: break; ! 150: ! 151: case 's': ! 152: lflag = 0; ! 153: break; ! 154: ! 155: case 'u': ! 156: case 'w': ! 157: firstchar = argv[1][i]; ! 158: break; ! 159: ! 160: default: ! 161: printf("Bad flag %s\n", argv[1]); ! 162: exit(1); ! 163: } ! 164: } ! 165: } else { ! 166: if (!isalnum(argv[1][0]) || argc > 2) { ! 167: printf("Usage: %s [ -hlsuw ] [ user ]\n", cp); ! 168: exit(1); ! 169: } else ! 170: sel_user = argv[1]; ! 171: } ! 172: argc--; argv++; ! 173: } ! 174: ! 175: if ((kmem = open("/dev/kmem", 0)) < 0) { ! 176: fprintf(stderr, "No kmem\n"); ! 177: exit(1); ! 178: } ! 179: nlist("/unix", nl); ! 180: if (nl[0].n_type==0) { ! 181: fprintf(stderr, "No namelist\n"); ! 182: exit(1); ! 183: } ! 184: ! 185: if (firstchar != 'u') ! 186: readpr(); ! 187: ! 188: ut = fopen("/etc/utmp","r"); ! 189: if (header) { ! 190: /* Print time of day */ ! 191: time(&now); ! 192: nowt = localtime(&now); ! 193: prtat(nowt); ! 194: ! 195: /* ! 196: * Print how long system has been up. ! 197: * (Found by looking for "bootime" in kernel) ! 198: */ ! 199: lseek(kmem, (long)nl[X_BOOTIME].n_value, 0); ! 200: read(kmem, &bootime, sizeof (bootime)); ! 201: ! 202: uptime = now - bootime; ! 203: days = uptime / (60*60*24); ! 204: uptime %= (60*60*24); ! 205: hrs = uptime / (60*60); ! 206: uptime %= (60*60); ! 207: mins = DIV60(uptime); ! 208: ! 209: printf(" up"); ! 210: if (days > 0) ! 211: printf(" %d day%s,", days, days>1?"s":""); ! 212: if (hrs > 0 && mins > 0) { ! 213: printf(" %2d:%02d,", hrs, mins); ! 214: } else { ! 215: if (hrs > 0) ! 216: printf(" %d hr%s,", hrs, hrs>1?"s":""); ! 217: if (mins > 0) ! 218: printf(" %d min%s,", mins, mins>1?"s":""); ! 219: } ! 220: ! 221: /* Print number of users logged in to system */ ! 222: while (fread(&utmp, sizeof(utmp), 1, ut)) { ! 223: if (utmp.ut_name[0] != '\0' && ! 224: strncmp(utmp.ut_line, "pt/", sizeof("pt/") - 1)) ! 225: nusers++; ! 226: } ! 227: rewind(ut); ! 228: printf(" %d users", nusers); ! 229: ! 230: /* ! 231: * Print 1, 5, and 15 minute load averages. ! 232: * (Found by looking in kernel for avenrun). ! 233: */ ! 234: printf(", load average:"); ! 235: lseek(kmem, (long)nl[X_AVENRUN].n_value, 0); ! 236: read(kmem, avenrun, sizeof(avenrun)); ! 237: for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) { ! 238: if (i > 0) ! 239: printf(","); ! 240: printf(" %.2f", avenrun[i]); ! 241: } ! 242: printf("\n"); ! 243: if (firstchar == 'u') ! 244: exit(0); ! 245: ! 246: /* Headers for rest of output */ ! 247: if (lflag) ! 248: printf("User tty login@ idle JCPU %%CPU %%MEM %%IN what\n"); ! 249: else ! 250: printf("User tty idle what\n"); ! 251: if (debug) ! 252: printf("ecmx = %d CLSIZE = %d\n", ecmx, CLSIZE); ! 253: fflush(stdout); ! 254: } ! 255: ! 256: ! 257: for (;;) { /* for each entry in utmp */ ! 258: if (fread(&utmp, sizeof(utmp), 1, ut) == NULL) { ! 259: fclose(ut); ! 260: exit(0); ! 261: } ! 262: if (utmp.ut_name[0] == '\0') ! 263: continue; /* that tty is free */ ! 264: if (sel_user && strncmp(utmp.ut_name, sel_user, NMAX) != 0) ! 265: continue; /* we wanted only somebody else */ ! 266: if (strncmp(utmp.ut_line, "pt/", sizeof("pt/") - 1) == 0) ! 267: continue; /* ignore pt/pt?? entries */ ! 268: ! 269: gettty(); ! 270: jobtime = 0; ! 271: percentcpu = 0; ! 272: pagesused = 0; ! 273: pagesresident = 0; ! 274: strcpy(doing, "-"); /* default act: normally never prints */ ! 275: empty = 1; ! 276: curpid = -1; ! 277: idle = findidle(); ! 278: for (i=0; i<np; i++) { /* for each process on this tty */ ! 279: if (!(TTYEQ)) ! 280: continue; ! 281: jobtime += pr[i].w_time + pr[i].w_ctime; ! 282: pagesused += pr[i].w_size; ! 283: pagesresident += pr[i].w_rss; ! 284: if ((pr[i].w_flag&SLOAD) && pr[i].w_ptime != 0) ! 285: percentcpu += ! 286: 100.0 * pr[i].w_pctcpu ! 287: /* / (1.0 - exp(pr[i].w_ptime * (-1.0/20.0))) */; ! 288: if (debug) { ! 289: printf("\t\t%d\t%s", pr[i].w_pid, pr[i].w_args); ! 290: printf(" %f %d %d %x %d", pr[i].w_pctcpu * 100.0, ! 291: pr[i].w_size, pr[i].w_rss, pr[i].w_flag, ! 292: pr[i].w_ptime); ! 293: printf("\n"); ! 294: } ! 295: if (empty && pr[i].w_igintr!=IGINT) { ! 296: empty = 0; ! 297: curpid = -1; ! 298: } ! 299: if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){ ! 300: curpid = pr[i].w_pid; ! 301: strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm); ! 302: #ifdef notdef ! 303: if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') { ! 304: strcat(doing, " ("); ! 305: strcat(doing, pr[i].w_comm); ! 306: strcat(doing, ")"); ! 307: } ! 308: #endif ! 309: } ! 310: } ! 311: putline(); ! 312: } ! 313: } ! 314: ! 315: /* figure out the major/minor device # pair for this tty */ ! 316: gettty() ! 317: { ! 318: char ttybuf[sizeof "/dev/" + sizeof utmp.ut_line]; ! 319: struct stat statbuf; ! 320: ! 321: strcpy(ttybuf, "/dev/"); ! 322: strncat(ttybuf, utmp.ut_line, sizeof utmp.ut_line); ! 323: stat(ttybuf, &statbuf); ! 324: tty = statbuf.st_ino; ! 325: } ! 326: ! 327: /* ! 328: * putline: print out the accumulated line of info about one user. ! 329: */ ! 330: putline() ! 331: { ! 332: register int tm; ! 333: ! 334: /* print login name of the user */ ! 335: printf("%-*.*s ", NMAX, NMAX, utmp.ut_name); ! 336: ! 337: /* print tty user is on */ ! 338: if (lflag) ! 339: /* long form: all (up to) LMAX chars */ ! 340: printf("%-*.*s", LMAX, LMAX, utmp.ut_line); ! 341: else { ! 342: /* short form: 2 chars, skipping 'tty' if there */ ! 343: if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y') ! 344: printf("%-2.2s", &utmp.ut_line[3]); ! 345: else ! 346: printf("%-2.2s", utmp.ut_line); ! 347: } ! 348: ! 349: if (lflag) ! 350: /* print when the user logged in */ ! 351: prtat(localtime(&utmp.ut_time)); ! 352: ! 353: /* print idle time */ ! 354: prttime(idle," "); ! 355: ! 356: if (lflag) { ! 357: /* print CPU time for all processes & children */ ! 358: prttime(DIV60(jobtime)," "); ! 359: /* print cpu time for interesting process */ ! 360: printf("%5.1f%5.1f%5.1f", ! 361: percentcpu, ! 362: (ecmx ? 100.0*pagesresident/(float)ecmx/(float)CLSIZE : 0), ! 363: (pagesused ? 100.0*pagesresident/pagesused : 0)); ! 364: } ! 365: ! 366: /* what user is doing, either command tail or args */ ! 367: printf(" %-.32s\n",doing); ! 368: fflush(stdout); ! 369: } ! 370: ! 371: /* find & return number of minutes current tty has been idle */ ! 372: findidle() ! 373: { ! 374: struct stat stbuf; ! 375: long lastaction, diff; ! 376: char ttyname[sizeof "/dev/" + sizeof utmp.ut_line]; ! 377: ! 378: strcpy(ttyname, "/dev/"); ! 379: strncat(ttyname, utmp.ut_line, LMAX); ! 380: stat(ttyname, &stbuf); ! 381: time(&now); ! 382: lastaction = stbuf.st_atime; ! 383: diff = now - lastaction; ! 384: diff = DIV60(diff); ! 385: if (diff < 0) diff = 0; ! 386: return(diff); ! 387: } ! 388: ! 389: /* ! 390: * prttime prints a time in hours and minutes. ! 391: * The character string tail is printed at the end, obvious ! 392: * strings to pass are "", " ", or "am". ! 393: */ ! 394: prttime(tim, tail) ! 395: time_t tim; ! 396: char *tail; ! 397: { ! 398: register int didhrs = 0; ! 399: ! 400: if (tim >= 60) { ! 401: printf("%3d:", tim/60); ! 402: didhrs++; ! 403: } else { ! 404: printf(" "); ! 405: } ! 406: tim %= 60; ! 407: if (tim > 0 || didhrs) { ! 408: printf(didhrs&&tim<10 ? "%02d" : "%2d", tim); ! 409: } else { ! 410: printf(" "); ! 411: } ! 412: printf("%s", tail); ! 413: } ! 414: ! 415: /* prtat prints a 12 hour time given a pointer to a time of day */ ! 416: prtat(p) ! 417: struct tm *p; ! 418: { ! 419: register int t, pm; ! 420: ! 421: t = p -> tm_hour; ! 422: pm = (t > 11); ! 423: if (t > 11) ! 424: t -= 12; ! 425: if (t == 0) ! 426: t = 12; ! 427: prttime(t*60 + p->tm_min, pm ? "pm" : "am"); ! 428: } ! 429: ! 430: /* ! 431: * readpr finds and reads in the array pr, containing the interesting ! 432: * parts of the proc and user tables for each live process. ! 433: */ ! 434: readpr() ! 435: { ! 436: int pn, mf, addr, c; ! 437: int szpt, pfnum, i; ! 438: int usize; ! 439: ino_t findtty(); ! 440: struct pte *Usrptma, *usrpt, *pte, apte; ! 441: struct dblock db; ! 442: ! 443: Usrptma = (struct pte *) nl[X_USRPTMA].n_value; ! 444: usrpt = (struct pte *) nl[X_USRPT].n_value; ! 445: if((mem = open("/dev/mem", 0)) < 0) { ! 446: fprintf(stderr, "No mem\n"); ! 447: exit(1); ! 448: } ! 449: if ((swap = open("/dev/drum", 0)) < 0) { ! 450: fprintf(stderr, "No drum\n"); ! 451: exit(1); ! 452: } ! 453: /* ! 454: * read mem to find swap dev. ! 455: */ ! 456: lseek(kmem, (long)nl[X_SWAPDEV].n_value, 0); ! 457: read(kmem, &nl[X_SWAPDEV].n_value, sizeof(nl[X_SWAPDEV].n_value)); ! 458: /* ! 459: * Find base of swap ! 460: */ ! 461: lseek(kmem, (long)nl[X_NSWAP].n_value, 0); ! 462: read(kmem, &nswap, sizeof(nswap)); ! 463: lseek(kmem, (long)nl[X_ECMX].n_value, 0); ! 464: if (read(kmem, &ecmx, sizeof (ecmx)) != sizeof (ecmx)) { ! 465: fprintf(stderr, "Can't read ecmx\n"); ! 466: exit(1); ! 467: } ! 468: /* ! 469: * Locate proc table ! 470: */ ! 471: lseek(kmem, (long)nl[X_NPROC].n_value, 0); ! 472: read(kmem, &nproc, sizeof(nproc)); ! 473: pr = (struct pr *)calloc(nproc, sizeof (struct pr)); ! 474: f = (struct find *)calloc(nproc, sizeof(struct find)); ! 475: np = 0; ! 476: lseek(kmem, (long)nl[X_PROC].n_value, 0); ! 477: read(kmem, &aproc, sizeof(aproc)); ! 478: for (pn=0; pn<nproc; pn++) { ! 479: lseek(kmem, (int)(aproc + pn), 0); ! 480: read(kmem, &mproc, sizeof mproc); ! 481: /* decide if it's an interesting process */ ! 482: if (mproc.p_stat==0 || mproc.p_pgrp==0) ! 483: continue; ! 484: f[pn].f_parent = &f[((unsigned)mproc.p_pptr ! 485: - (unsigned)aproc) / sizeof(mproc)]; ! 486: if (mproc.p_flag&SDETACH) ! 487: continue; ! 488: /* find & read in the user structure */ ! 489: if ((mproc.p_flag & SLOAD) == 0) { ! 490: /* not in memory - get from swap device */ ! 491: addr = mproc.p_swaddr<<9; ! 492: lseek(swap, (long)addr, 0); ! 493: if (read(swap, &up, sizeof(up)) != sizeof(up)) { ! 494: continue; ! 495: } ! 496: } else { ! 497: int p0br, cc; ! 498: #define INTPPG (NBPG / sizeof (int)) ! 499: struct pte pagetbl[NBPG / sizeof (struct pte)]; ! 500: /* loaded, get each page from memory separately */ ! 501: szpt = mproc.p_szpt; ! 502: p0br = (int)mproc.p_p0br; ! 503: pte = &Usrptma[btokmx(mproc.p_p0br) + szpt-1]; ! 504: lseek(kmem, (long)pte, 0); ! 505: if (read(kmem, &apte, sizeof(apte)) != sizeof(apte)) ! 506: continue; ! 507: lseek(mem, ctob(apte.pg_pfnum), 0); ! 508: if (read(mem,pagetbl,sizeof(pagetbl)) != sizeof(pagetbl)) ! 509: cont: ! 510: continue; ! 511: usize = sizeof(up); ! 512: for(cc=0; cc<UPAGES; cc++) { /* get u area */ ! 513: int upage = pagetbl[NPTEPG-UPAGES+cc].pg_pfnum; ! 514: int size = usize > NBPG ? NBPG : usize; ! 515: usize -= size; ! 516: lseek(mem,ctob(upage),0); ! 517: if (read(mem,((int *)&up)+INTPPG*cc,size) != size) ! 518: goto cont; ! 519: } ! 520: szpt = up.u_pcb.pcb_szpt; ! 521: pr[np].w_seekaddr = ctob(apte.pg_pfnum); ! 522: } ! 523: vstodb(0, CLSIZE, &up.u_smap, &db, 1); ! 524: pr[np].w_lastpg = ctob(db.db_base); ! 525: if (up.u_ttyino == 0) ! 526: continue; ! 527: ! 528: /* save the interesting parts */ ! 529: f[pn].f_pr = &pr[np]; ! 530: pr[np].w_pid = mproc.p_pid; ! 531: pr[np].w_flag = mproc.p_flag; ! 532: if (mproc.p_stat != SIDL && mproc.p_stat != SZOMB) ! 533: pr[np].w_size = mproc.p_dsize + mproc.p_ssize; ! 534: pr[np].w_pctcpu = mproc.p_pctcpu; ! 535: pr[np].w_ptime = mproc.p_time; ! 536: if (mproc.p_stat != SIDL && mproc.p_stat != SZOMB) ! 537: pr[np].w_rss = mproc.p_rssize; ! 538: pr[np].w_igintr = (((int)up.u_signal[2]==1) + 2*((int)up.u_signal[2]>1) + 3*((int)up.u_signal[3]==1)) + 6*((int)up.u_signal[3]>1); ! 539: pr[np].w_time = up.u_vm.vm_utime + up.u_vm.vm_stime; ! 540: pr[np].w_ctime = up.u_cvm.vm_utime + up.u_cvm.vm_stime; ! 541: pr[np].w_tty = up.u_ttyino; ! 542: strncpy(pr[np].w_comm, up.u_comm, sizeof(up.u_comm)); ! 543: /* ! 544: * Get args if there's a chance we'll print it. ! 545: * Cant just save pointer: getargs returns static place. ! 546: * Cant use strcpyn: that crock blank pads. ! 547: */ ! 548: pr[np].w_args[0] = 0; ! 549: strncat(pr[np].w_args,getargs(&pr[np]),ARGWIDTH); ! 550: if (pr[np].w_args[0]==0 || pr[np].w_args[0]=='-' && pr[np].w_args[1]<=' ' || pr[np].w_args[0] == '?') { ! 551: strcat(pr[np].w_args, " ("); ! 552: strcat(pr[np].w_args, pr[np].w_comm); ! 553: strcat(pr[np].w_args, ")"); ! 554: } ! 555: np++; ! 556: } ! 557: /* fix tty names for /dev/pt/pt?? */ ! 558: for (pn = 0; pn < nproc; ++pn) ! 559: if (f[pn].f_pr) ! 560: f[pn].f_pr->w_tty = findtty(&f[pn]); ! 561: } ! 562: ! 563: /* ! 564: * getargs: given a pointer to a proc structure, this looks at the swap area ! 565: * and tries to reconstruct the arguments. This is straight out of ps. ! 566: */ ! 567: char * ! 568: getargs(p) ! 569: struct pr *p; ! 570: { ! 571: int c, addr, nbad; ! 572: static int abuf[CLSIZE*NBPG/sizeof(int)]; ! 573: struct pte pagetbl[NPTEPG]; ! 574: register int *ip; ! 575: register char *cp, *cp1; ! 576: ! 577: if ((p->w_flag & SLOAD) == 0) { ! 578: lseek(swap, p->w_lastpg, 0); ! 579: if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf)) ! 580: return(p->w_comm); ! 581: } else { ! 582: c = p->w_seekaddr; ! 583: lseek(mem,c,0); ! 584: if (read(mem,pagetbl,NBPG) != NBPG) ! 585: return(p->w_comm); ! 586: if (pagetbl[NPTEPG-CLSIZE-UPAGES].pg_fod==0 && pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum) { ! 587: lseek(mem,ctob(pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum),0); ! 588: if (read(mem,abuf,sizeof(abuf)) != sizeof(abuf)) ! 589: return(p->w_comm); ! 590: } else { ! 591: lseek(swap, p->w_lastpg, 0); ! 592: if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf)) ! 593: return(p->w_comm); ! 594: } ! 595: } ! 596: abuf[sizeof(abuf)/sizeof(abuf[0])-1] = 0; ! 597: for (ip = &abuf[sizeof(abuf)/sizeof(abuf[0])-2]; ip > abuf;) { ! 598: /* Look from top for -1 or 0 as terminator flag. */ ! 599: if (*--ip == -1 || *ip == 0) { ! 600: cp = (char *)(ip+1); ! 601: if (*cp==0) ! 602: cp++; ! 603: nbad = 0; /* up to 5 funny chars as ?'s */ ! 604: for (cp1 = cp; cp1 < (char *)&abuf[sizeof(abuf)/sizeof(abuf[0])]; cp1++) { ! 605: c = *cp1&0177; ! 606: if (c==0) /* nulls between args => spaces */ ! 607: *cp1 = ' '; ! 608: else if (c < ' ' || c > 0176) { ! 609: if (++nbad >= 5) { ! 610: *cp1++ = ' '; ! 611: break; ! 612: } ! 613: *cp1 = '?'; ! 614: } else if (c=='=') { /* Oops - found an ! 615: * environment var, back ! 616: * over & erase it. */ ! 617: *cp1 = 0; ! 618: while (cp1>cp && *--cp1!=' ') ! 619: *cp1 = 0; ! 620: break; ! 621: } ! 622: } ! 623: while (*--cp1==' ') /* strip trailing spaces */ ! 624: *cp1 = 0; ! 625: return(cp); ! 626: } ! 627: } ! 628: return (p->w_comm); ! 629: } ! 630: ! 631: /* ! 632: * Given a base/size pair in virtual swap area, ! 633: * return a physical base/size pair which is the ! 634: * (largest) initial, physically contiguous block. ! 635: */ ! 636: vstodb(vsbase, vssize, dmp, dbp, rev) ! 637: register int vsbase; ! 638: int vssize; ! 639: struct dmap *dmp; ! 640: register struct dblock *dbp; ! 641: { ! 642: register int blk = DMMIN; ! 643: register swblk_t *ip = dmp->dm_map; ! 644: ! 645: if (vsbase < 0 || vsbase + vssize > dmp->dm_size) ! 646: panic("vstodb"); ! 647: while (vsbase >= blk) { ! 648: vsbase -= blk; ! 649: if (blk < DMMAX) ! 650: blk *= 2; ! 651: ip++; ! 652: } ! 653: if (*ip <= 0 || *ip + blk > nswap) ! 654: panic("vstodb *ip"); ! 655: dbp->db_size = min(vssize, blk - vsbase); ! 656: dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); ! 657: } ! 658: ! 659: panic(cp) ! 660: char *cp; ! 661: { ! 662: ! 663: /* printf("%s\n", cp); */ ! 664: } ! 665: ! 666: min(a, b) ! 667: { ! 668: ! 669: return (a < b ? a : b); ! 670: } ! 671: ! 672: ino_t ! 673: findtty(fp) ! 674: struct find *fp; ! 675: { ! 676: if (fp->f_tty) ! 677: return(fp->f_tty); ! 678: if (isttyinode(fp->f_pr->w_tty)) ! 679: return(fp->f_tty = fp->f_pr->w_tty); ! 680: return(fp->f_tty = findtty(fp->f_parent)); ! 681: } ! 682: ! 683: static char *dirlist[] = { ! 684: "/dev/", ! 685: "/dev/dk/", ! 686: 0 ! 687: }; ! 688: ! 689: #define BITSPERBYTE 8 ! 690: #define BITMAP 1024 ! 691: ! 692: char inodes[BITMAP]; ! 693: ! 694: isttyinode(i) ! 695: ino_t i; ! 696: { ! 697: register char **dpp, *dp; ! 698: int fd; ! 699: struct direct db; ! 700: static init = 0; ! 701: ! 702: if (init == 0) { ! 703: for (dpp = dirlist; dp = *dpp++;) { ! 704: if ((fd = open(dp, 0)) < 0) ! 705: continue; ! 706: while (read(fd, (char *) &db, sizeof(db)) == sizeof(db)) ! 707: inodes[db.d_ino / BITSPERBYTE] |= (1 << ! 708: (db.d_ino % BITSPERBYTE)); ! 709: close(fd); ! 710: } ! 711: ++init; ! 712: } ! 713: return(inodes[i / BITSPERBYTE] & (1 << (i % BITSPERBYTE))); ! 714: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.