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