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; }
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(struct chan *c, void *va, long n, int64_t off) { ERRSTACK(1); char buf[256], ch; long l, bp; char *a; //Mach *mp; int id, fd; struct chan *swc; uint32_t offset; struct cmdbuf *cb; struct cmdtab *ct; int x; uint64_t rip, rsp, cr3, flags, vcpu; int ret; struct vmctl vmctl; a = va; offset = off; 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: 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) { kbd.raw = 1; /* clumsy hack - wake up reader */ ch = 0; qwrite(kbdq, &ch, 1); } else if (strncmp(a, "rawoff", 6) == 0) { kbd.raw = 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, ' ')) != NULL) a++; } break; case Qtime: if (!iseve()) error(EPERM, "Hodie Natus Est Radici Frater"); return writetime(a, n); case Qbintime: if (!iseve()) error(EPERM, ERROR_FIXME); return writebintime(a, n); #if 0 case Qhostowner: return hostownerwrite(a, n); case Qhostdomain: return hostdomainwrite(a, n); case Quser: return userwrite(a, n); #endif case Qnull: break; case Qconfig: error(EPERM, "Cannot write to config QID"); break; case Qsysctl: //if (!iseve()) error(EPERM, ERROR_FIXME); cb = parsecmd(a, n); if (cb->nf > 1) printd("cons sysctl cmd %s\n", cb->f[0]); case Qreboot: if (!iseve()) error(EPERM, ERROR_FIXME); cb = parsecmd(a, n); if (waserror()) { kfree(cb); nexterror(); } ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg)); switch (ct->index) { case CMhalt: cpu_halt(); break; case CMbroken: keepbroken = 1; break; case CMnobroken: keepbroken = 0; break; case CMreboot: reboot(); break; case CMpanic: *(uint32_t *) 0 = 0; panic("/dev/reboot"); } poperror(); kfree(cb); break; #if 0 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(EINVAL, "n is bigger than sizeof buf for Qswap"); 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, ERROR_FIXME); if (buf[0] < '0' || '9' < buf[0]) error(EINVAL, ERROR_FIXME); fd = strtoul(buf, 0, 0); swc = fdtochan(fd, -1, 1, 1); setswapchan(swc); break; #endif case Qsysname: if (offset != 0) error(EINVAL, ERROR_FIXME); if (n <= 0 || n >= sizeof buf) error(EINVAL, ERROR_FIXME); strncpy(buf, a, n); buf[n] = 0; if (buf[n - 1] == '\n') buf[n - 1] = 0; kstrdup(&sysname, buf); break; default: printd("conswrite: %#llux\n", c->qid.path); error(EINVAL, "bad QID in conswrite"); } return n; }