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