#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "../port/error.h"#include <version.h>#include "mp.h"#include "libsec.h"#include "keyboard.h" extern int cflag;extern int keepbroken; void (*serwrite)(char *, int); Queue* kscanq; /* keyboard raw scancodes (when needed) */char* kscanid; /* name of raw scan format (if defined) */Queue* kbdq; /* unprocessed console input */Queue* lineq; /* processed console input */Queue* printq; /* console output */Queue* klogq; /* kernel print (log) output */int iprintscreenputs; static struct{ RWlock; Queue* q;} kprintq; static struct{ QLock; int raw; /* true if we shouldn't process input */ int ctl; /* number of opens to the control file */ int kbdr; /* number of open reads to the keyboard */ int scan; /* true if reading raw scancodes */ int x; /* index into line */ char line[1024]; /* current input line */ char c; int count; int repeat;} kbd; char* sysname;char* eve; enum{ CMreboot, CMhalt, CMpanic, CMbroken, CMnobroken, CMconsole,}; static Cmdtab sysctlcmd[] ={ CMreboot, "reboot", 0, CMhalt, "halt", 0, CMpanic, "panic", 0, CMconsole, "console", 1, CMbroken, "broken", 0, CMnobroken, "nobroken", 0,}; voidprintinit(void){ lineq = qopen(2*1024, 0, nil, nil); if(lineq == nil) panic("printinit"); qnoblock(lineq, 1);} /* * return true if current user is eve */intiseve(void){ Osenv *o; o = up->env; return strcmp(eve, o->user) == 0;} static intconsactive(void){ if(printq) return qlen(printq) > 0; return 0;} static voidprflush(void){ ulong now; now = m->ticks; while(serwrite==nil && consactive()) if(m->ticks - now >= HZ) break;} /* * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. */static voidputstrn0(char *str, int n, int usewrite){ int m; char *t; char buf[PRINTSIZE+2]; /* * if kprint is open, put the message there, otherwise * if there's an attached bit mapped display, * put the message there. */ m = consoleprint; if(canrlock(&kprintq)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq); nexterror(); } if(usewrite) qwrite(kprintq.q, str, n); else qiwrite(kprintq.q, str, n); poperror(); m = 0; } runlock(&kprintq); } if(m && screenputs != nil) screenputs(str, n); /* * if there's a serial line being used as a console, * put the message there. */ if(serwrite != nil) { serwrite(str, n); return; } if(printq == 0) return; while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t - str; if(m > sizeof(buf)-2) m = sizeof(buf)-2; memmove(buf, str, m); buf[m] = '\r'; buf[m+1] = '\n'; if(usewrite) qwrite(printq, buf, m+2); else qiwrite(printq, buf, m+2); str = t + 1; n -= m + 1; } else { if(usewrite) qwrite(printq, str, n); else qiwrite(printq, str, n); break; } }} voidputstrn(char *str, int n){ putstrn0(str, n, 0);} intsnprint(char *s, int n, char *fmt, ...){ va_list arg; va_start(arg, fmt); n = vseprint(s, s+n, fmt, arg) - s; va_end(arg); return n;} intsprint(char *s, char *fmt, ...){ int n; va_list arg; va_start(arg, fmt); n = vseprint(s, s+PRINTSIZE, fmt, arg) - s; va_end(arg); return n;} intprint(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return n;} intfprint(int fd, char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; USED(fd); va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return n;} intkprint(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);} 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); uartputs(buf, n); splx(s); return n;} voidpanic(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; setpanic(); kprintq.q = nil; strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf)-1, fmt, arg) - buf; va_end(arg); buf[n] = '\n'; putstrn(buf, n+1); spllo(); dumpstack(); exit(1);} void_assert(char *fmt){ panic("assert failed: %s", fmt);} voidsysfatal(char *fmt, ...){ va_list arg; char buf[64]; va_start(arg, fmt); vsnprint(buf, sizeof(buf), fmt, arg); va_end(arg); panic("sysfatal: %s", buf);} intpprint(char *fmt, ...){ int n; Chan *c; Osenv *o; va_list arg; char buf[2*PRINTSIZE]; n = sprint(buf, "%s %ld: ", up->text, up->pid); va_start(arg, fmt); n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); o = up->env; if(o->fgrp == 0) { print("%s", buf); return 0; } c = o->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) { print("%s", buf); return 0; } if(waserror()) { print("%s", buf); return 0; } devtab[c->type]->write(c, buf, n, c->offset); poperror(); lock(c); c->offset += n; unlock(c); return n;} voidecho(Rune r, char *buf, int n){ if(kbd.raw) return; if(r == '\n'){ if(printq) qiwrite(printq, "\r", 1); } else if(r == 0x15){ buf = "^U\n"; n = 3; } if(consoleprint && screenputs != nil) screenputs(buf, n); if(printq) qiwrite(printq, buf, n);} /* * Debug key support. Allows other parts of the kernel to register debug * key handlers, instead of devcons.c having to know whatever's out there. * A kproc is used to invoke most handlers, rather than tying up the CPU at * splhi, which can choke some device drivers (eg softmodem). */typedef struct { Rune r; char *m; void (*f)(Rune); int i; /* function called at interrupt time */} Dbgkey; static struct { Rendez; Dbgkey *work; Dbgkey keys[50]; int nkeys; int on;} dbg; static Dbgkey *finddbgkey(Rune r){ int i; Dbgkey *dp; for(dp = dbg.keys, i = 0; i < dbg.nkeys; i++, dp++) if(dp->r == r) return dp; return nil;} static intdbgwork(void *){ return dbg.work != 0;} static voiddbgproc(void *){ Dbgkey *dp; setpri(PriRealtime); for(;;) { do { sleep(&dbg, dbgwork, 0); dp = dbg.work; } while(dp == nil); dp->f(dp->r); dbg.work = nil; }} voiddebugkey(Rune r, char *msg, void (*fcn)(), int iflag){ Dbgkey *dp; if(dbg.nkeys >= nelem(dbg.keys)) return; if(finddbgkey(r) != nil) return; for(dp = &dbg.keys[dbg.nkeys++] - 1; dp >= dbg.keys; dp--) { if(strcmp(dp->m, msg) < 0) break; dp[1] = dp[0]; } dp++; dp->r = r; dp->m = msg; dp->f = fcn; dp->i = iflag;} static intisdbgkey(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;} static voiddbgtoggle(Rune){Lines 1–500 of 1274. Load more
#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include <version.h> #include "mp.h" #include "libsec.h" #include "keyboard.h" extern int cflag; extern int keepbroken; void (*serwrite)(char *, int); Queue* kscanq; /* keyboard raw scancodes (when needed) */ char* kscanid; /* name of raw scan format (if defined) */ Queue* kbdq; /* unprocessed console input */ Queue* lineq; /* processed console input */ Queue* printq; /* console output */ Queue* klogq; /* kernel print (log) output */ int iprintscreenputs; static struct { RWlock; Queue* q; } kprintq; static struct { QLock; int raw; /* true if we shouldn't process input */ int ctl; /* number of opens to the control file */ int kbdr; /* number of open reads to the keyboard */ int scan; /* true if reading raw scancodes */ int x; /* index into line */ char line[1024]; /* current input line */ char c; int count; int repeat; } kbd; char* sysname; char* eve; enum { CMreboot, CMhalt, CMpanic, CMbroken, CMnobroken, CMconsole, }; static Cmdtab sysctlcmd[] = { CMreboot, "reboot", 0, CMhalt, "halt", 0, CMpanic, "panic", 0, CMconsole, "console", 1, CMbroken, "broken", 0, CMnobroken, "nobroken", 0, }; void printinit(void) { lineq = qopen(2*1024, 0, nil, nil); if(lineq == nil) panic("printinit"); qnoblock(lineq, 1); } /* * return true if current user is eve */ int iseve(void) { Osenv *o; o = up->env; return strcmp(eve, o->user) == 0; } static int consactive(void) { if(printq) return qlen(printq) > 0; return 0; } static void prflush(void) { ulong now; now = m->ticks; while(serwrite==nil && consactive()) if(m->ticks - now >= HZ) break; } /* * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. */ static void putstrn0(char *str, int n, int usewrite) { int m; char *t; char buf[PRINTSIZE+2]; /* * if kprint is open, put the message there, otherwise * if there's an attached bit mapped display, * put the message there. */ m = consoleprint; if(canrlock(&kprintq)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq); nexterror(); } if(usewrite) qwrite(kprintq.q, str, n); else qiwrite(kprintq.q, str, n); poperror(); m = 0; } runlock(&kprintq); } if(m && screenputs != nil) screenputs(str, n); /* * if there's a serial line being used as a console, * put the message there. */ if(serwrite != nil) { serwrite(str, n); return; } if(printq == 0) return; while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t - str; if(m > sizeof(buf)-2) m = sizeof(buf)-2; memmove(buf, str, m); buf[m] = '\r'; buf[m+1] = '\n'; if(usewrite) qwrite(printq, buf, m+2); else qiwrite(printq, buf, m+2); str = t + 1; n -= m + 1; } else { if(usewrite) qwrite(printq, str, n); else qiwrite(printq, str, n); break; } } } void putstrn(char *str, int n) { putstrn0(str, n, 0); } int snprint(char *s, int n, char *fmt, ...) { va_list arg; va_start(arg, fmt); n = vseprint(s, s+n, fmt, arg) - s; va_end(arg); return n; } int sprint(char *s, char *fmt, ...) { int n; va_list arg; va_start(arg, fmt); n = vseprint(s, s+PRINTSIZE, fmt, arg) - s; va_end(arg); return n; } int print(char *fmt, ...) { int n; va_list arg; char buf[PRINTSIZE]; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return n; } int fprint(int fd, char *fmt, ...) { int n; va_list arg; char buf[PRINTSIZE]; USED(fd); va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return n; } 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); } int iprint(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); uartputs(buf, n); splx(s); return n; } void panic(char *fmt, ...) { int n; va_list arg; char buf[PRINTSIZE]; setpanic(); kprintq.q = nil; strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf)-1, fmt, arg) - buf; va_end(arg); buf[n] = '\n'; putstrn(buf, n+1); spllo(); dumpstack(); exit(1); } void _assert(char *fmt) { panic("assert failed: %s", fmt); } void sysfatal(char *fmt, ...) { va_list arg; char buf[64]; va_start(arg, fmt); vsnprint(buf, sizeof(buf), fmt, arg); va_end(arg); panic("sysfatal: %s", buf); } int pprint(char *fmt, ...) { int n; Chan *c; Osenv *o; va_list arg; char buf[2*PRINTSIZE]; n = sprint(buf, "%s %ld: ", up->text, up->pid); va_start(arg, fmt); n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); o = up->env; if(o->fgrp == 0) { print("%s", buf); return 0; } c = o->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) { print("%s", buf); return 0; } if(waserror()) { print("%s", buf); return 0; } devtab[c->type]->write(c, buf, n, c->offset); poperror(); lock(c); c->offset += n; unlock(c); return n; } void echo(Rune r, char *buf, int n) { if(kbd.raw) return; if(r == '\n'){ if(printq) qiwrite(printq, "\r", 1); } else if(r == 0x15){ buf = "^U\n"; n = 3; } if(consoleprint && screenputs != nil) screenputs(buf, n); if(printq) qiwrite(printq, buf, n); } /* * Debug key support. Allows other parts of the kernel to register debug * key handlers, instead of devcons.c having to know whatever's out there. * A kproc is used to invoke most handlers, rather than tying up the CPU at * splhi, which can choke some device drivers (eg softmodem). */ typedef struct { Rune r; char *m; void (*f)(Rune); int i; /* function called at interrupt time */ } Dbgkey; static struct { Rendez; Dbgkey *work; Dbgkey keys[50]; int nkeys; int on; } dbg; static Dbgkey * finddbgkey(Rune r) { int i; Dbgkey *dp; for(dp = dbg.keys, i = 0; i < dbg.nkeys; i++, dp++) if(dp->r == r) return dp; return nil; } static int dbgwork(void *) { return dbg.work != 0; } static void dbgproc(void *) { Dbgkey *dp; setpri(PriRealtime); for(;;) { do { sleep(&dbg, dbgwork, 0); dp = dbg.work; } while(dp == nil); dp->f(dp->r); dbg.work = nil; } } void debugkey(Rune r, char *msg, void (*fcn)(), int iflag) { Dbgkey *dp; if(dbg.nkeys >= nelem(dbg.keys)) return; if(finddbgkey(r) != nil) return; for(dp = &dbg.keys[dbg.nkeys++] - 1; dp >= dbg.keys; dp--) { if(strcmp(dp->m, msg) < 0) break; dp[1] = dp[0]; } dp++; dp->r = r; dp->m = msg; dp->f = fcn; dp->i = iflag; } 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; } static void dbgtoggle(Rune) {