📄 devcons.c
字号:
} qnoblock(kprintoq, 1); }else qreopen(kprintoq); c->iounit = qiomaxatomic; break; case Qsecstore: if(omode == ORDWR) error(Eperm); if(omode != OREAD) memset(secstorebuf, 0, sizeof secstorebuf); break; case Qsnarf: if(omode == ORDWR) error(Eperm); if(omode == OREAD) c->aux = strdup(""); else c->aux = mallocz(SnarfSize, 1); break; } return c;}static voidconsclose(Chan *c){ switch((ulong)c->qid.path){ /* last close of control file turns off raw */ case Qconsctl: if(c->flag&COPEN){ qlock(&kbd.lk); if(--kbd.ctl == 0) kbd.raw = 0; qunlock(&kbd.lk); } break; /* close of kprint allows other opens */ case Qkprint: if(c->flag & COPEN){ kprintinuse = 0; qhangup(kprintoq, nil); } break; case Qsnarf: if(c->mode == OWRITE) clipwrite(c->aux); free(c->aux); break; }}static longconsread(Chan *c, void *buf, long n, vlong off){ char *b; char tmp[128]; /* must be >= 6*NUMSIZE */ char *cbuf = buf; int ch, i, eol; 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(); } if(kbd.raw) { if(qcanread(lineq)) n = qread(lineq, buf, n); else { /* read as much as possible */ do { i = qread(kbdq, cbuf, n); cbuf += i; n -= i; } while (n>0 && qcanread(kbdq)); n = cbuf - (char*)buf; } } else { while(!qcanread(lineq)) { qread(kbdq, &kbd.line[kbd.x], 1); ch = kbd.line[kbd.x]; eol = 0; switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case '\n': case 0x04: eol = 1; default: kbd.line[kbd.x++] = ch; break; } if(kbd.x == sizeof(kbd.line) || eol){ if(ch == 0x04) kbd.x--; qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); } qunlock(&kbd.lk); poperror(); return n; case Qcpunote: sleep(&up->sleep, return0, nil); case Qcputime: return 0; 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 Qsnarf: if(offset == 0){ free(c->aux); c->aux = clipread(); } if(c->aux == nil) return 0; return readstr(offset, buf, n, c->aux); case Qsecstore: return readstr(offset, buf, n, secstorebuf); case Qsysstat: return 0; case Qswap: return 0; 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 */}static longconswrite(Chan *c, void *va, long n, vlong off){ char buf[256]; long l, bp; char *a = va; int fd; Chan *swc; ulong offset = off; Cmdbuf *cb; Cmdtab *ct; switch((ulong)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(buf, 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.lk); if(kbd.x){ qwrite(kbdq, kbd.line, kbd.x); kbd.x = 0; } kbd.raw = 1; qunlock(&kbd.lk); } else if(strncmp(a, "rawoff", 6) == 0){ qlock(&kbd.lk); kbd.raw = 0; kbd.x = 0; qunlock(&kbd.lk); } 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 Qhostowner: return hostownerwrite(a, n); case Qhostdomain: return hostdomainwrite(a, n); case Quser: return userwrite(a, n); case Qnull: break; case Qreboot: if(!iseve()) error(Eperm); cb = parsecmd(a, n); if(waserror()) { free(cb); nexterror(); } ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg)); switch(ct->index) { case CMreboot: rebootcmd(cb->nf-1, cb->f+1); break; case CMpanic: panic("/dev/reboot"); } poperror(); free(cb); break; case Qsecstore: if(offset >= sizeof secstorebuf || offset+n+1 >= sizeof secstorebuf) error(Etoobig); secstoretab->qid.vers++; memmove(secstorebuf+offset, va, n); return n; case Qshowfile: return showfilewrite(a, n); case Qsnarf: if(offset >= SnarfSize || offset+n >= SnarfSize) error(Etoobig); snarftab->qid.vers++; memmove((uchar*)c->aux+offset, va, n); return n; case Qsysstat: n = 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 >= sizeof buf) error(Ebadarg); strncpy(buf, a, n); buf[n] = 0; if(buf[n-1] == '\n') buf[n-1] = 0; kstrdup(&sysname, buf); break; default: print("conswrite: 0x%llux\n", c->qid.path); error(Egreg); } return n;}Dev consdevtab = { 'c', "cons", devreset, consinit, devshutdown, consattach, conswalk, consstat, consopen, devcreate, consclose, consread, devbread, conswrite, devbwrite, devremove, devwstat,};static uvlong uvorder = (uvlong) 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]; nsec = todget(&ticks); if(fasthz == (vlong)0) fastticks((uvlong*)&fasthz); sec = nsec/((uvlong) 1000000000); 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*((vlong) 1000000000); 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 == (vlong)0) 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;}intiprint(char *fmt, ...){ int n, s; va_list arg; char buf[PRINTSIZE]; s = splhi(); va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); if(screenputs != nil && iprintscreenputs) screenputs(buf, n);#undef write write(2, buf, n); splx(s); return n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -