📄 devcons.c
字号:
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 Qkey: return keyread(buf, n, offset); case Qauth: return authread(c, cbuf, n); case Qauthcheck: return authcheckread(c, cbuf, n); case Qauthent: return authentread(c, cbuf, 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*8+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; *bp++ = '\n'; } } n = readstr((ulong)offset, buf, n, b); free(b); return n; case Qswap: sprint(tmp, "%lud/%lud memory %lud/%lud swap\n", palloc.user-palloc.freecount, palloc.user, conf.nswap-swapalloc.free, conf.nswap); return readstr((ulong)offset, buf, n, tmp); case Qsysname: 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); n = readstr((ulong)offset, buf, n, b); free(b); return n; case Qzero: memset(buf, 0, n); return n; default: print("consread %lux\n", c->qid.path); error(Egreg); } return -1; /* never reached */}static longconswrite(Chan *c, void *va, long n, vlong off){ char buf[256]; long l, bp; char *a = va; Mach *mp; int id, fd; Chan *swc; ulong offset = off; switch(c->qid.path){ case Qcons: /* * Can't page fault in putstrn, so copy the data locally. */ l = n; while(l > 0){ bp = l; if(bp > sizeof buf) bp = sizeof buf; memmove(buf, a, bp); putstrn0(a, bp, 1); a += bp; l -= bp; } break; case Qconsctl: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ qlock(&kbd); if(kbd.x){ qwrite(kbdq, kbd.line, kbd.x); kbd.x = 0; } kbd.raw = 1; qunlock(&kbd); } else if(strncmp(a, "rawoff", 6) == 0){ kbd.raw = 0; kbd.x = 0; } else if(strncmp(a, "ctlpon", 6) == 0){ kbd.ctlpoff = 0; } else if(strncmp(a, "ctlpoff", 7) == 0){ kbd.ctlpoff = 1; } if(a = strchr(a, ' ')) a++; } break; case Qtime: if(!iseve()) error(Eperm); return writetime(a, n); case Qbintime: if(!iseve()) error(Eperm); return writebintime(a, n); case Qkey: return keywrite(a, n); case Qhostowner: return hostownerwrite(a, n); case Qhostdomain: return hostdomainwrite(a, n); case Quser: return userwrite(a, n); case Qauth: return authwrite(c, a, n); case Qauthcheck: return authcheck(c, a, n); case Qauthent: return authentwrite(c, a, n); case Qnull: break; case Qreboot: if(!iseve()) error(Eperm); if(strncmp(a, "reboot", 6) == 0){ print("conswrite: reboot\n"); exit(0); } if(strncmp(a, "malloc", 6) == 0){ /* rsc bug */ a = malloc(2); strcpy(a, "hi"); free(a); a = malloc(2); strcpy(a, "helo"); free(a); panic("not reached conswrite"); } if(strncmp(a, "panic", 5) == 0) panic("/dev/reboot"); break; case Qsysstat: for(id = 0; id < 32; id++) { if(active.machs & (1<<id)) { mp = MACHP(id); mp->cs = 0; mp->intr = 0; mp->syscall = 0; mp->pfault = 0; mp->tlbfault = 0; mp->tlbpurge = 0; } } break; case Qswap: if(n >= sizeof buf) error(Egreg); memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; /* start a pager if not already started */ if(strncmp(buf, "start", 5) == 0){ kickpager(); break; } if(cpuserver && !iseve()) error(Eperm); if(buf[0]<'0' || '9'<buf[0]) error(Ebadarg); fd = strtoul(buf, 0, 0); swc = fdtochan(fd, -1, 1, 1); setswapchan(swc); break; case Qsysname: if(offset != 0) error(Ebadarg); if(n <= 0 || n >= NAMELEN) error(Ebadarg); strncpy(sysname, a, n); sysname[n] = 0; if(sysname[n-1] == '\n') sysname[n-1] = 0; break; default: print("conswrite: %lud\n", c->qid.path); error(Egreg); } return n;}voidsetterm(char *f){ char buf[2*NAMELEN]; sprint(buf, f, conffile); ksetenv("terminal", buf);}Dev consdevtab = { 'c', "cons", devreset, consinit, consattach, devclone, conswalk, consstat, consopen, devcreate, consclose, consread, devbread, conswrite, devbwrite, devremove, devwstat,};struct Rb{ QLock; Rendez producer; Rendez consumer; ulong randomcount; uchar buf[1024]; uchar *ep; uchar *rp; uchar *wp; uchar next; uchar wakeme; ushort bits; ulong randn;} rb;static voidseedrand(void){ randomread((void*)&rb.randn, sizeof(rb.randn));}intnrand(int n){ if(rb.randn == 0) seedrand(); rb.randn = rb.randn*1103515245 + 12345 + MACHP(0)->ticks; return (rb.randn>>16) % n;}intrand(void){ nrand(1); return rb.randn;}static intrbnotfull(void*){ int i; i = rb.rp - rb.wp; return i != 1 && i != (1 - sizeof(rb.buf));}static intrbnotempty(void*){ return rb.wp != rb.rp;}voidgenrandom(void*){ up->basepri = PriNormal; up->priority = up->basepri; for(;;){ for(;;) if(++rb.randomcount > 100000) break; if(anyhigher()) sched(); if(!rbnotfull(0)) sleep(&rb.producer, rbnotfull, 0); }}/* * produce random bits in a circular buffer */static voidrandomclock(void){ if(rb.randomcount == 0 || !rbnotfull(0)) return; rb.bits = (rb.bits<<2) ^ rb.randomcount; rb.randomcount = 0; rb.next++; if(rb.next != 8/2) return; rb.next = 0; *rb.wp ^= rb.bits; if(rb.wp+1 == rb.ep) rb.wp = rb.buf; else rb.wp = rb.wp+1; if(rb.wakeme) wakeup(&rb.consumer);}static voidrandominit(void){ addclock0link(randomclock); rb.ep = rb.buf + sizeof(rb.buf); rb.rp = rb.wp = rb.buf; kproc("genrandom", genrandom, 0);}/* * consume random bytes from a circular buffer */static ulongrandomread(void *xp, ulong n){ uchar *e, *p; ulong x; p = xp; if(waserror()){ qunlock(&rb); nexterror(); } qlock(&rb); for(e = p + n; p < e; ){ if(rb.wp == rb.rp){ rb.wakeme = 1; wakeup(&rb.producer); sleep(&rb.consumer, rbnotempty, 0); rb.wakeme = 0; continue; } /* * beating clocks will be precictable if * they are synchronized. Use a cheap pseudo * random number generator to obscure any cycles. */ x = rb.randn*1103515245 ^ *rb.rp; *p++ = rb.randn = x; if(rb.rp+1 == rb.ep) rb.rp = rb.buf; else rb.rp = rb.rp+1; } qunlock(&rb); poperror(); wakeup(&rb.producer); return n;}static uvlong uvorder = 0x0001020304050607ULL;static uchar*le2vlong(vlong *to, uchar *f){ uchar *t, *o; int i; t = (uchar*)to; o = (uchar*)&uvorder; for(i = 0; i < sizeof(vlong); i++) t[o[i]] = f[i]; return f+sizeof(vlong);}static uchar*vlong2le(uchar *t, vlong from){ uchar *f, *o; int i; f = (uchar*)&from; o = (uchar*)&uvorder; for(i = 0; i < sizeof(vlong); i++) t[i] = f[o[i]]; return t+sizeof(vlong);}static long order = 0x00010203;static uchar*le2long(long *to, uchar *f){ uchar *t, *o; int i; t = (uchar*)to; o = (uchar*)ℴ for(i = 0; i < sizeof(long); i++) t[o[i]] = f[i]; return f+sizeof(long);}static uchar*long2le(uchar *t, long from){ uchar *f, *o; int i; f = (uchar*)&from; o = (uchar*)ℴ for(i = 0; i < sizeof(long); i++) t[i] = f[o[i]]; return t+sizeof(long);}char *Ebadtimectl = "bad time control";/* * like the old #c/time but with added info. Return * * secs nanosecs fastticks fasthz */static intreadtime(ulong off, char *buf, int n){ vlong nsec, ticks; long sec; char str[7*NUMSIZE+4]; // extra 4 bytes are null plus doprint // reserving space for a frigging UTF // char nsec = todget(&ticks); if(fasthz == 0LL) fastticks((uvlong*)&fasthz); sec = nsec/1000000000ULL; snprint(str, sizeof(str), "%*.0lud %*.0llud %*.0llud %*.0llud ", NUMSIZE-1, sec, VLNUMSIZE-1, nsec, VLNUMSIZE-1, ticks, VLNUMSIZE-1, fasthz); return readstr(off, buf, n, str);}/* * set the time in seconds */static intwritetime(char *buf, int n){ char b[13]; long i; vlong now; if(n >= sizeof(b)) error(Ebadtimectl); strncpy(b, buf, n); b[n] = 0; i = strtol(b, 0, 0); if(i <= 0) error(Ebadtimectl); now = i*1000000000LL; todset(now, 0, 0); return n;}/* * read binary time info. all numbers are little endian. * ticks and nsec are syncronized. */static intreadbintime(char *buf, int n){ int i; vlong nsec, ticks; uchar *b = (uchar*)buf; i = 0; if(fasthz == 0LL) fastticks((uvlong*)&fasthz); nsec = todget(&ticks); if(n >= 3*sizeof(uvlong)){ vlong2le(b+2*sizeof(uvlong), fasthz); i += sizeof(uvlong); } if(n >= 2*sizeof(uvlong)){ vlong2le(b+sizeof(uvlong), ticks); i += sizeof(uvlong); } if(n >= 8){ vlong2le(b, nsec); i += sizeof(vlong); } return i;}/* * set any of the following * - time in nsec * - nsec trim applied over some seconds * - clock frequency */static intwritebintime(char *buf, int n){ uchar *p; vlong delta; long period; n--; p = (uchar*)buf + 1; switch(*buf){ case 'n': if(n < sizeof(vlong)) error(Ebadtimectl); le2vlong(&delta, p); todset(delta, 0, 0); break; case 'd': if(n < sizeof(vlong)+sizeof(long)) error(Ebadtimectl); p = le2vlong(&delta, p); le2long(&period, p); todset(-1, delta, period); break; case 'f': if(n < sizeof(uvlong)) error(Ebadtimectl); le2vlong(&fasthz, p); todsetfreq(fasthz); break; } return n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -