static void dbgblock(Prog *p) { Osenv *o; Progctl *ctl; o = p->osenv; ctl = o->debug; qproduce(ctl->q, progstate[p->state], strlen(progstate[p->state])); pushrun(p); p->addrun = dbgaddrun; o->rend = &up->sleep; /* * bdone(p) is safe after release because p is being debugged, * so cannot exit. */ if(waserror()){ acquire(); nexterror(); } release(); if(o->rend != nil) Sleep(o->rend, bdone, p); poperror(); acquire(); if(p->kill != nil) error(p->kill); ctl = o->debug; if(ctl != nil) qproduce(ctl->q, "run", 3); }
void gkbdputc(Queue *q, int ch) { int n; Rune r; static uchar kc[5*UTFmax]; static int nk, collecting = 0; char buf[UTFmax]; r = ch; if(r == Latin) { collecting = 1; nk = 0; return; } if(collecting) { int c; nk += runetochar((char*)&kc[nk], &r); c = latin1(kc, nk); if(c < -1) /* need more keystrokes */ return; collecting = 0; if(c == -1) { /* invalid sequence */ qproduce(q, kc, nk); return; } r = (Rune)c; } n = runetochar(buf, &r); if(n == 0) return; /* if(!isdbgkey(r)) */ qproduce(q, buf, n); }
/* * called with ucb locked (and c locked if user initiated close) */ void relhangup(Conv *c, Reliable *r) { int n; Block *bp; char hup[ERRMAX]; n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); qproduce(c->eq, hup, n); /* * dump any unacked outgoing messages */ for(bp = r->unacked; bp != nil; bp = r->unacked){ r->unacked = bp->list; bp->list = nil; freeb(bp); } r->rcvgen = 0; r->rcvseq = 0; r->acksent = 0; if(generation == Hangupgen) generation++; r->sndgen = generation++; r->sndseq = 0; r->ackrcvd = 0; r->xmits = 0; r->timeout = 0; wakeup(&r->vous); }
/* * Put character, possibly a rune, into read queue at interrupt time. * Performs translation for compose sequences * Called at interrupt time to process a character. */ int kbdputc(struct queue *q, int ch) { int n; char buf[3]; Rune r; static Rune kc[15]; static int nk, collecting = 0; r = ch; if (r == Latin) { collecting = 1; nk = 0; return 0; } if (collecting) { int c; nk += runetochar((char *unused_char_p_t)&kc[nk], &r); c = latin1(kc, nk); if (c < -1) /* need more keystrokes */ return 0; collecting = 0; if (c == -1) { /* invalid sequence */ echo(kc[0], (char *unused_char_p_t)kc, nk); qproduce(q, kc, nk); return 0; } r = (Rune) c; }
/* process individual kbd characters */ void readkbd(uv_stream_t* stream, ssize_t nread, const uv_buf_t *buf) { char* ch; int i; for (ch=buf->base, i=0; i<nread; i++) { if(nread < 0) { print("keyboard close (n=%d, %s)\n", nread, strerror(errno)); } switch(*ch) { case '\r': *ch = '\n'; break; case DELETE: *ch = '\b'; break; } if(kbd.raw == 0){ switch(*ch){ case 0x15: write(1, "^U\n", 3); break; default: write(1, ch, 1); break; } } qproduce(kbdq, ch, 1); uv_async_send(&ev_conschar); } if (buf->base) {free(buf->base);} }
static void psauxputc(int c, int) { uchar uc; uc = c; qproduce(psauxq, &uc, 1); }
static void cmdproc(void *a) { Conv *c; int n = 0; char status[ERRMAX]; void *t = NULL; c = a; qlock(&c->l); if(Debug) print("f[0]=%q f[1]=%q\n", c->cmd->f[0], c->cmd->f[1]); if(waserror()){ if(Debug) print("failed: %q\n", up->errstr); kstrdup(&c->error, up->errstr); c->state = "Done"; qunlock(&c->l); // Wakeup(&c->startr); pexit("cmdproc", 0); } // t = oscmd(c->cmd->f+1, c->nice, c->dir, c->fd); // if(t == nil) // oserror(); c->child = t; /* to allow oscmdkill */ poperror(); qunlock(&c->l); // Wakeup(&c->startr); if(Debug) print("started\n"); // while(waserror()) // oscmdkill(t); // osenter(); mwait(&c->p->ac->icc->fn); // n = oscmdwait(t, status, sizeof(status)); // osleave(); if(n < 0){ // oserrstr(up->genbuf, sizeof(up->genbuf)); n = snprint(status, sizeof(status), "0 0 0 0 %q", up->genbuf); } qlock(&c->l); c->child = nil; // oscmdfree(t); if(Debug){ status[n]=0; print("done %d %d %d: %q\n", c->fd[0], c->fd[1], c->fd[2], status); } if(c->inuse > 0){ c->state = "Done"; if(c->waitq != nil) qproduce(c->waitq, status, n); }else closeconv(c); qunlock(&c->l); pexit("", 0); }
/* * Put character, possibly a rune, into read queue at interrupt time. * Performs translation for compose sequences * Called at interrupt time to process a character. */ int kbdputc(Queue *q, int ch) { int n; char buf[3]; Rune r; static Rune kc[15]; static int nk, collecting = 0; r = ch; if(r == Latin) { collecting = 1; nk = 0; return 0; } if(collecting) { int c; nk += runetochar((char*)&kc[nk], &r); c = latin1(kc, nk); if(c < -1) /* need more keystrokes */ return 0; collecting = 0; if(c == -1) { /* invalid sequence */ echo(kc[0], (char*)kc, nk); qproduce(q, kc, nk); return 0; } r = (Rune)c; } kbd.c = r; n = runetochar(buf, &r); if(n == 0) return 0; if(!isdbgkey(r)) { echo(r, buf, n); qproduce(q, buf, n); } return 0; }
int kprint(char *fmt, ...) { va_list arg; char buf[PRINTSIZE]; int n; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); if(qfull(klogq)) qflush(klogq); return qproduce(klogq, buf, n); }
void kbdslave(void *a) { char b; USED(a); for(;;) { b = readkbd(); if(kbd.raw == 0) write(1, &b, 1); qproduce(kbdq, &b, 1); } pexit("kbdslave", 0); }
static void uartrecvq(Uart *p) { uchar *cp = p->istage; int n = p->ip - cp; if(n == 0) return; if(p->putc) while(n-- > 0) p->putc(p->iq, *cp++); else if(p->iq) if(qproduce(p->iq, p->istage, n) < n) print("qproduce flow control"); p->ip = p->istage; }
static int isdbgkey(Rune r) { static int ctrlt; Dbgkey *dp; int echoctrlt = ctrlt; /* * ^t hack BUG */ if(dbg.on || (ctrlt >= 2)) { if(r == 0x14 || r == 0x05) { ctrlt++; return 0; } if(dp = finddbgkey(r)) { if(dp->i || ctrlt > 2) dp->f(r); else { dbg.work = dp; wakeup(&dbg); } ctrlt = 0; return 1; } ctrlt = 0; } else if(r == 0x14){ ctrlt++; return 1; } else ctrlt = 0; if(echoctrlt){ char buf[3]; buf[0] = 0x14; while(--echoctrlt >= 0){ echo(buf[0], buf, 1); qproduce(kbdq, buf, 1); } } return 0; }
void dbgexit(Prog *kid, int broken, char *estr) { int n; Osenv *e; Progctl *ctl; char buf[ERRMAX+20]; e = kid->osenv; ctl = e->debug; e->debug = nil; kid->xec = xec; if(broken) n = snprint(buf, sizeof(buf), "broken: %s", estr); else n = snprint(buf, sizeof(buf), "exited"); if(ctl->debugger) telldbg(ctl, buf); qproduce(ctl->q, buf, n); }
void kbdslave(void *a) { char b; USED(a); for(;;) { b = readkbd(); if(kbd.raw == 0){ switch(b){ case 0x15: write(1, "^U\n", 3); break; default: write(1, &b, 1); break; } } qproduce(kbdq, &b, 1); } /* pexit("kbdslave", 0); */ /* not reached */ }
/* * Move data from the interrupt staging area to * the input Queue. */ static void uartstageinput(Uart *p) { int n; uint8_t *ir, *iw; while(p->ir != p->iw){ ir = p->ir; if(p->ir > p->iw){ iw = p->ie; p->ir = p->istage; } else{ iw = p->iw; p->ir = p->iw; } if((n = qproduce(p->iq, ir, iw - ir)) < 0){ p->serr++; (*p->phys->rts)(p, 0); } else if(n == 0) p->berr++; } }
void echo(char *buf, int n) { static int ctrlt; int x; char *e, *p; if(n == 0) return; e = buf+n; for(p = buf; p < e; p++){ switch(*p){ case 0x10: /* ^P */ if(cpuserver && !kbd.ctlpoff){ active.exiting = 1; return; } break; case 0x14: /* ^T */ ctrlt++; if(ctrlt > 2) ctrlt = 2; continue; } if(ctrlt != 2) continue; /* ^T escapes */ ctrlt = 0; switch(*p){ case 'S': x = splhi(); dumpstack(); procdump(); splx(x); return; case 's': dumpstack(); return; case 'x': xsummary(); ixsummary(); mallocsummary(); // memorysummary(); pagersummary(); return; case 'd': if(consdebug == nil) consdebug = rdb; else consdebug = nil; print("consdebug now 0x%p\n", consdebug); return; case 'D': if(consdebug == nil) consdebug = rdb; consdebug(); return; case 'p': x = spllo(); procdump(); splx(x); return; case 'q': scheddump(); return; case 'k': killbig("^t ^t k"); return; case 'r': exit(0); return; } } qproduce(kbdq, buf, n); if(kbd.raw) return; kmesgputs(buf, n); if(screenputs != nil) echoscreen(buf, n); uartecho(buf, n); // Plan 9 VX }
static void echo(char *buf, int n) { static int ctrlt, pid; char *e, *p; if (n == 0) return; e = buf + n; for (p = buf; p < e; p++) { switch (*p) { #if 0 case 0x10: /* ^P */ if (cpuserver && !kbd.ctlpoff) { active.exiting = 1; return; } break; #endif case 0x14: /* ^T */ ctrlt++; if (ctrlt > 2) ctrlt = 2; continue; } if (ctrlt != 2) continue; /* ^T escapes */ ctrlt = 0; switch (*p) { #if 0 case 'S': { int8_t x = 0; disable_irqsave(&x); dumpstack(); procdump(); enable_irqsave(&x); return; } #endif case 's': dumpstack(); return; #if 0 case 'x': xsummary(); ixsummary(); mallocsummary(); memorysummary(); pagersummary(); return; case 'd': if (consdebug == NULL) consdebug = rdb; else consdebug = NULL; printd("consdebug now %#p\n", consdebug); return; case 'D': if (consdebug == NULL) consdebug = rdb; consdebug(); return; case 'p': x = spllo(); procdump(); splx(x); return; case 'q': scheddump(); return; case 'k': killbig("^t ^t k"); return; #endif case 'r': exit(0); return; } } qproduce(kbdq, buf, n); if (kbd.raw) return; kmesgputs(buf, n); if (screenputs != NULL) echoscreen(buf, n); if (serialoq) echoserialoq(buf, n); }
void dbgxec(Prog *p) { Bpt *b; Prog *kid; Osenv *env; Progctl *ctl; int op, pc, n; char buf[ERRMAX+10]; extern void (*dec[])(void); env = p->osenv; ctl = env->debug; ctl->ref++; if(waserror()){ closedbgctl(ctl, p); nexterror(); } R = p->R; R.MP = R.M->MP; R.IC = p->quanta; if((ulong)R.IC > ctl->step) R.IC = ctl->step; if(ctl->stop) R.IC = 0; buf[0] = '\0'; if(R.IC != 0 && R.M->compiled) { comvec(); if(p != currun()) dbgblock(p); goto save; } while(R.IC != 0) { if(0) print("step: %lux: %s %4ld %D\n", (ulong)p, R.M->m->name, R.PC-R.M->prog, R.PC); dec[R.PC->add](); op = R.PC->op; R.PC++; optab[op](); /* * check notification about new progs */ if(op == ISPAWN || op == IMSPAWN) { /* pick up the kid from the end of the run queue */ kid = delruntail(Pdebug); n = snprint(buf, sizeof buf, "new %d", kid->pid); qproduce(ctl->q, buf, n); buf[0] = '\0'; } if(op == ILOAD) { n = snprint(buf, sizeof buf, "load %s", string2c(*(String**)R.s)); qproduce(ctl->q, buf, n); buf[0] = '\0'; } /* * check for returns at big steps */ if(op == IRET) R.IC = 1; /* * check for blocked progs */ if(R.IC == 1 && p != currun()) dbgblock(p); if(ctl->stop) R.IC = 1; R.IC--; if(ctl->bpts == nil) continue; pc = R.PC - R.M->prog; for(b = ctl->bpts; b != nil; b = b->next) { if(pc == b->pc && (strcmp(R.M->m->path, b->path) == 0 || strcmp(R.M->m->path, b->file) == 0)) { strcpy(buf, "breakpoint"); goto save; } } } save: if(ctl->stop) strcpy(buf, "stopped"); p->R = R; if(env->debug == nil) { poperror(); return; } if(p == currun()) delrun(Pdebug); telldbg(env->debug, buf); poperror(); closedbgctl(env->debug, p); }