static int32_t consread(Chan *c, void *buf, int32_t n, int64_t off) { Proc *up = externup(); uint64_t l; Mach *mp; char *b, *bp, *s, *e; char tmp[512]; /* Qswap is 381 bytes at clu */ int i, k, id; int32_t offset; if(n <= 0) return n; offset = off; switch((uint32_t)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); case Qcons: error(Egreg); case Qcputime: k = offset; if(k >= 6*NUMSIZE) return 0; if(k+n > 6*NUMSIZE) n = 6*NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*i<k+n; i++){ l = up->time[i]; if(i == TReal) l = sys->ticks - l; l = TK2MS(l); readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memmove(buf, tmp+k, n); return n; case Qkmesg: /* * This is unlocked to avoid tying up a process * that's writing to the buffer. kmesg.n never * gets smaller, so worst case the reader will * see a slurred buffer. */ if(off >= kmesg.n) n = 0; else{ if(off+n > kmesg.n) n = kmesg.n - off; memmove(buf, kmesg.buf+off, n); } return n; case Qkprint: error(Egreg); case Qpgrpid: return readnum(offset, buf, n, up->pgrp->pgrpid, NUMSIZE); case Qpid: return readnum(offset, buf, n, up->pid, NUMSIZE); case Qppid: return readnum(offset, buf, n, up->parentpid, NUMSIZE); case Qtime: return readtime(offset, buf, n); case Qbintime: return readbintime(buf, n); case Qhostowner: return readstr(offset, buf, n, eve); case Qhostdomain: return readstr(offset, buf, n, hostdomain); case Quser: return readstr(offset, buf, n, up->user); case Qnull: return 0; case Qsysstat: n = MACHMAX*(NUMSIZE*11+2+1); b = smalloc(n + 1); /* +1 for NUL */ bp = b; e = bp + n; for(id = 0; id < MACHMAX; id++) if((mp = sys->machptr[id]) != nil && mp->online){ readnum(0, bp, NUMSIZE, mp->machno, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, sys->load, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inidle*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inintr*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, 0, NUMSIZE); /* sched # */ bp += NUMSIZE; bp = strecpy(bp, e, rolename[mp->NIX.nixtype]); *bp++ = '\n'; } if(waserror()){ free(b); nexterror(); } n = readstr(offset, buf, n, b); free(b); poperror(); return n; case Qswap: tmp[0] = 0; s = seprintpagestats(tmp, tmp + sizeof tmp); s = seprintphysstats(s, tmp + sizeof tmp); b = buf; l = s - tmp; i = readstr(offset, b, l, tmp); b += i; n -= i; if(offset > l) offset -= l; else offset = 0; return i + mallocreadsummary(c, b, n, offset); case Qsysname: if(sysname == nil) return 0; return readstr(offset, buf, n, sysname); case Qrandom: return randomread(buf, n); case Qurandom: return urandomread(buf, n); case Qdrivers: return devtabread(c, buf, n, off); case Qzero: memset(buf, 0, n); return n; case Qosversion: snprint(tmp, sizeof tmp, "2000"); n = readstr(offset, buf, n, tmp); return n; case Qdebug: s = seprint(tmp, tmp + sizeof tmp, "locks %lu\n", lockstats.locks); s = seprint(s, tmp + sizeof tmp, "glare %lu\n", lockstats.glare); s = seprint(s, tmp + sizeof tmp, "inglare %lu\n", lockstats.inglare); s = seprint(s, tmp + sizeof tmp, "qlock %lu\n", qlockstats.qlock); seprint(s, tmp + sizeof tmp, "qlockq %lu\n", qlockstats.qlockq); return readstr(offset, buf, n, tmp); break; case Qsyscall: snprint(tmp, sizeof tmp, "%s", printallsyscalls ? "on" : "off"); return readstr(offset, buf, n, tmp); break; default: print("consread %#llx\n", c->qid.path); error(Egreg); } return -1; /* never reached */ }
static long consread(struct chan *c, void *buf, long n, int64_t off) { ERRSTACK(1); uint32_t l; #if 0 Mach *mp; #endif char *b, *bp, ch; char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */ int i, k, id, send; int64_t offset = off; #if 0 extern char configfile[]; #endif if (n <= 0) return n; switch ((uint32_t) c->qid.path) { case Qdir: return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen); case Qcons: qlock(&(&kbd)->qlock); if (waserror()) { qunlock(&(&kbd)->qlock); nexterror(); } while (!qcanread(lineq)) { if (qread(kbdq, &ch, 1) == 0) continue; send = 0; if (ch == 0) { /* flush output on rawoff -> rawon */ if (kbd.x > 0) send = !qcanread(kbdq); } else if (kbd.raw) { kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); } else { switch (ch) { case '\b': if (kbd.x > 0) kbd.x--; break; case 0x15: /* ^U */ kbd.x = 0; break; case '\n': case 0x04: /* ^D */ send = 1; default: if (ch != 0x04) kbd.line[kbd.x++] = ch; break; } } if (send || kbd.x == sizeof kbd.line) { qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); qunlock(&(&kbd)->qlock); poperror(); return n; #if 0 case Qcputime: k = offset; if (k >= 6 * NUMSIZE) return 0; if (k + n > 6 * NUMSIZE) n = 6 * NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) { l = current->time[i]; if (i == TReal) l = MACHP(0)->ticks - l; l = TK2MS(l); consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE); } memmove(buf, tmp + k, n); return n; #endif case Qkmesg: /* * This is unlocked to avoid tying up a process * that's writing to the buffer. kmesg.n never * gets smaller, so worst case the reader will * see a slurred buffer. */ if (off >= kmesg.n) n = 0; else { if (off + n > kmesg.n) n = kmesg.n - off; memmove(buf, kmesg.buf + off, n); } return n; case Qkprint: return qread(kprintoq, buf, n); case Qpgrpid: return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid, NUMSIZE); case Qpid: return consreadnum((uint32_t) offset, buf, n, current->pid, NUMSIZE); case Qppid: return consreadnum((uint32_t) offset, buf, n, current->ppid, NUMSIZE); case Qtime: return readtime((uint32_t) offset, buf, n); case Qbintime: return readbintime(buf, n); case Qhostowner: return consreadstr((uint32_t) offset, buf, n, eve); case Qhostdomain: return consreadstr((uint32_t) offset, buf, n, hostdomain); case Quser: return consreadstr((uint32_t) offset, buf, n, current->user); case Qnull: return 0; #if 0 case Qconfig: return consreadstr((uint32_t) offset, buf, n, configfile); case Qsysstat: b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0); /* +1 for NUL */ bp = b; for (id = 0; id < 32; id++) { if (active.machs & (1 << id)) { mp = MACHP(id); consreadnum(0, bp, NUMSIZE, id, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, (mp->perf.avg_inidle * 100) / mp->perf.period, NUMSIZE); bp += NUMSIZE; consreadnum(0, bp, NUMSIZE, (mp->perf.avg_inintr * 100) / mp->perf.period, NUMSIZE); bp += NUMSIZE; *bp++ = '\n'; } } if (waserror()) { kfree(b); nexterror(); } n = consreadstr((uint32_t) offset, buf, n, b); kfree(b); poperror(); return n; case Qswap: snprintf(tmp, sizeof tmp, "%lud memory\n" "%d pagesize\n" "%lud kernel\n" "%lud/%lud user\n" "%lud/%lud swap\n" "%lud/%lud kernel malloc\n" "%lud/%lud kernel draw\n", conf.npage * BY2PG, BY2PG, conf.npage - conf.upages, palloc.user - palloc.freecount, palloc.user, conf.nswap - swapalloc.free, conf.nswap, mainmem->cursize, mainmem->maxsize, imagmem->cursize, imagmem->maxsize); return consreadstr((uint32_t) offset, buf, n, tmp); #endif case Qsysname: if (sysname == NULL) return 0; return consreadstr((uint32_t) offset, buf, n, sysname); case Qdrivers: b = kzmalloc(READSTR, 0); if (b == NULL) error(ENOMEM, "allocation for /dev/drivers read failed"); k = 0; for (int i = 0; &devtab[i] < __devtabend; i++) k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name); if (waserror()) { kfree(b); nexterror(); } n = consreadstr((uint32_t) offset, buf, n, b); kfree(b); poperror(); return n; case Qklog: //return qread(klogq, buf, n); /* the queue gives us some elasticity for log reading. */ if (!logqueue) logqueue = qopen(1 << 20, 0, 0, 0); if (logqueue) { int ret; /* atomic sets/gets are not that important in this case. */ reading_kmesg = 1; qwrite(logqueue, logbuffer, index); index = 0; ret = qread(logqueue, buf, n); reading_kmesg = 0; return ret; } break; case Qzero: memset(buf, 0, n); return n; case Qosversion: snprintf(tmp, sizeof tmp, "2000"); n = consreadstr((uint32_t) offset, buf, n, tmp); return n; default: printd("consread %#llux\n", c->qid.path); error(EINVAL, "bad QID in consread"); } return -1; /* never reached */ }
static long consread(Chan *c, void *buf, long n, vlong off) { ulong l; Mach *mp; char *b, *bp; char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */ int i, k, id; vlong offset = off; extern char configfile[]; if(n <= 0) return n; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); case Qcons: error(Egreg); case Qcputime: k = offset; if(k >= 6*NUMSIZE) return 0; if(k+n > 6*NUMSIZE) n = 6*NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*i<k+n; i++){ l = up->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; l = TK2MS(l); readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memmove(buf, tmp+k, n); return n; case Qkmesg: /* * This is unlocked to avoid tying up a process * that's writing to the buffer. kmesg.n never * gets smaller, so worst case the reader will * see a slurred buffer. */ if(off >= kmesg.n) n = 0; else{ if(off+n > kmesg.n) n = kmesg.n - off; memmove(buf, kmesg.buf+off, n); } return n; case Qkprint: return qread(kprintoq, buf, n); case Qpgrpid: return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE); case Qpid: return readnum((ulong)offset, buf, n, up->pid, NUMSIZE); case Qppid: return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE); case Qtime: return readtime((ulong)offset, buf, n); case Qbintime: return readbintime(buf, n); case Qhostowner: return readstr((ulong)offset, buf, n, eve); case Qhostdomain: return readstr((ulong)offset, buf, n, hostdomain); case Quser: return readstr((ulong)offset, buf, n, up->user); case Qnull: return 0; case Qconfig: return readstr((ulong)offset, buf, n, configfile); case Qsysstat: b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1); /* +1 for NUL */ bp = b; for(id = 0; id < 32; id++) { if(active.machs & (1<<id)) { mp = MACHP(id); readnum(0, bp, NUMSIZE, id, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->load, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inidle*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inintr*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; *bp++ = '\n'; } } if(waserror()){ free(b); nexterror(); } n = readstr((ulong)offset, buf, n, b); free(b); poperror(); return n; case Qswap: snprint(tmp, sizeof tmp, "%lud memory\n" "%d pagesize\n" "%lud kernel\n" "%lud/%lud user\n" "%lud/%lud swap\n" "%lud/%lud kernel malloc\n" "%lud/%lud kernel draw\n", conf.npage*BY2PG, BY2PG, conf.npage-conf.upages, palloc.user-palloc.freecount, palloc.user, conf.nswap-swapalloc.free, conf.nswap, mainmem->cursize, mainmem->maxsize, imagmem->cursize, imagmem->maxsize); return readstr((ulong)offset, buf, n, tmp); case Qsysname: if(sysname == nil) return 0; return readstr((ulong)offset, buf, n, sysname); case Qrandom: return randomread(buf, n); case Qdrivers: b = smalloc(READSTR); k = 0; for(i = 0; devtab[i] != nil; i++) k += snprint(b+k, READSTR-k, "#%C %s\n", devtab[i]->dc, devtab[i]->name); if(waserror()){ free(b); nexterror(); } n = readstr((ulong)offset, buf, n, b); poperror(); free(b); return n; case Qzero: memset(buf, 0, n); return n; case Qmordor: error("one does not simply read from mordor"); return 0; case Qosversion: snprint(tmp, sizeof tmp, "2000"); n = readstr((ulong)offset, buf, n, tmp); return n; default: print("consread %#llux\n", c->qid.path); error(Egreg); } return -1; /* never reached */ }
static long consread(Chan *c, void *buf, long n, vlong off) { ulong l; Mach *mp; char *b, *bp, ch; char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */ int i, k, id, send; vlong offset = off; if(n <= 0) return n; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); case Qcons: qlock(&kbd.lk); if(waserror()) { qunlock(&kbd.lk); nexterror(); } while(!qcanread(lineq)){ if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x > 0) kbd.x--; break; case 0x15: /* ^U */ kbd.x = 0; break; case '\n': case 0x04: /* ^D */ send = 1; default: if(ch != 0x04) kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); qunlock(&kbd.lk); poperror(); return n; case Qcputime: k = offset; if(k >= 6*NUMSIZE) return 0; if(k+n > 6*NUMSIZE) n = 6*NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*i<k+n; i++){ l = up->time[i]; if(i == TReal) l = msec() - l; l = TK2MS(l); readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memmove(buf, tmp+k, n); return n; case Qkmesg: /* * This is unlocked to avoid tying up a process * that's writing to the buffer. kmesg.n never * gets smaller, so worst case the reader will * see a slurred buffer. */ if(off >= kmesg.n) n = 0; else{ if(off+n > kmesg.n) n = kmesg.n - off; memmove(buf, kmesg.buf+off, n); } return n; case Qkprint: return qread(kprintoq, buf, n); case Qpgrpid: return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE); case Qpid: return readnum((ulong)offset, buf, n, up->pid, NUMSIZE); case Qppid: return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE); case Qtime: return readtime((ulong)offset, buf, n); case Qbintime: return readbintime(buf, n); case Qhostowner: return readstr((ulong)offset, buf, n, eve); case Qhostdomain: return readstr((ulong)offset, buf, n, hostdomain); case Quser: return readstr((ulong)offset, buf, n, up->user); case Qnull: return 0; case Qsysstat: b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1); /* +1 for NUL */ bp = b; for(id = 0; id < 32; id++) { if(active.machs & (1<<id)) { mp = MACHP(id); readnum(0, bp, NUMSIZE, id, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, mp->load, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inidle*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; readnum(0, bp, NUMSIZE, (mp->perf.avg_inintr*100)/mp->perf.period, NUMSIZE); bp += NUMSIZE; *bp++ = '\n'; } } if(waserror()){ free(b); nexterror(); } n = readstr((ulong)offset, buf, n, b); free(b); poperror(); return n; case Qswap: tmp[0] = 0; return readstr((ulong)offset, buf, n, tmp); case Qsysname: if(sysname == nil) return 0; return readstr((ulong)offset, buf, n, sysname); case Qrandom: return randomread(buf, n); case Qdrivers: b = malloc(READSTR); if(b == nil) error(Enomem); n = 0; for(i = 0; devtab[i] != nil; i++) n += snprint(b+n, READSTR-n, "#%C %s\n", devtab[i]->dc, devtab[i]->name); if(waserror()){ free(b); nexterror(); } n = readstr((ulong)offset, buf, n, b); free(b); poperror(); return n; case Qzero: memset(buf, 0, n); return n; case Qosversion: snprint(tmp, sizeof tmp, "2000"); n = readstr((ulong)offset, buf, n, tmp); return n; default: print("consread 0x%llux\n", c->qid.path); error(Egreg); } return -1; /* never reached */ }