static int32_t conswrite(Chan *c, void *va, int32_t n, int64_t off) { Proc *up = externup(); char buf[256]; int32_t l, bp; char *a; Mach *mp; int i; uint32_t offset; Cmdbuf *cb; Cmdtab *ct; a = va; offset = off; extern int printallsyscalls; switch((uint32_t)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: print("consctl\n"); if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "sys", 3) == 0) { printallsyscalls = ! printallsyscalls; print("%sracing syscalls\n", printallsyscalls ? "T" : "Not t"); } 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 CMhalt: reboot(nil, 0, 0); break; case CMreboot: rebootcmd(cb->nf-1, cb->f+1); break; case CMpanic: *(volatile uint32_t*)0=0; panic("/dev/reboot"); } poperror(); free(cb); break; case Qsysstat: for(i = 0; i < MACHMAX; i++) if((mp = sys->machptr[i]) != nil && mp->online){ mp = sys->machptr[i]; mp->cs = 0; mp->intr = 0; mp->syscall = 0; mp->pfault = 0; mp->tlbfault = 0; /* not updated */ mp->tlbpurge = 0; /* # mmuflushtlb */ } break; case Qswap: if(n >= sizeof buf) error(Egreg); memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; if(!iseve()) error(Eperm); if(buf[0]<'0' || '9'<buf[0]) error(Ebadarg); if(strncmp(buf, "start", 5) == 0){ print("request to start pager ignored\n"); break; } 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; case Qdebug: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; if(n > 0 && buf[n-1] == '\n') buf[n-1] = 0; error(Ebadctl); break; case Qsyscall: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; if(n > 0 && buf[n-1] == '\n') buf[n-1] = 0; // Doing strncmp right is just painful and overkill here. if (buf[0] == 'o') { if (buf[1] == 'n' && buf[2] == 0) { printallsyscalls = 1; break; } if (buf[1] == 'f' && buf[2] == 'f' && buf[3] == 0) { printallsyscalls = 0; break; } } error("#c/syscall: can only write on or off"); break; default: print("conswrite: %#llx\n", c->qid.path); error(Egreg); } return n; }
static long conswrite(Chan *c, void *va, long n, vlong off) { char buf[256]; long l, bp; char *a; Mach *mp; int id, fd; Chan *swc; ulong offset; Cmdbuf *cb; Cmdtab *ct; a = va; offset = off; 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: error(Egreg); 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 Qconfig: error(Eperm); 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 CMhalt: reboot(nil, 0, 0); break; case CMreboot: rebootcmd(cb->nf-1, cb->f+1); break; case CMpanic: *(ulong*)0=0; panic("/dev/reboot"); case CMrdb: if(consdebug == nil) consdebug = rdb; consdebug(); break; } poperror(); free(cb); 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(!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; case Qmordor: error("one does not simply write into mordor"); return 0; default: print("conswrite: %#llux\n", c->qid.path); error(Egreg); } return n; }