#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "../port/error.h" #include <authsrv.h> void (*consdebug)(void) = nil;void (*screenputs)(char*, int) = nil; Queue* kbdq; /* unprocessed console input */Queue* lineq; /* processed console input */Queue* serialoq; /* serial console output */Queue* kprintoq; /* console output, for /dev/kprint */ulong kprintinuse; /* test and set whether /dev/kprint is open */int iprintscreenputs = 1; static struct{ QLock; int raw; /* true if we shouldn't process input */ int ctl; /* number of opens to the control file */ int x; /* index into line */ char line[1024]; /* current input line */ int count; int ctlpoff; /* a place to save up characters at interrupt time before dumping them in the queue */ Lock lockputc; char istage[512]; char *iw; char *ir; char *ie;} kbd = { .iw = kbd.istage, .ir = kbd.istage, .ie = kbd.istage + sizeof(kbd.istage),}; char *sysname;vlong fasthz; static void seedrand(void);static int readtime(ulong, char*, int);static int readbintime(char*, int);static int writetime(char*, int);static int writebintime(char*, int); enum{ CMreboot, CMpanic,}; Cmdtab rebootmsg[] ={ CMreboot, "reboot", 0, CMpanic, "panic", 0,}; voidprintinit(void){ lineq = qopen(2*1024, 0, 0, 0); if(lineq == nil) panic("printinit"); qnoblock(lineq, 1);} intconsactive(void){ if(serialoq) return qlen(serialoq) > 0; return 0;} voidprflush(void){ ulong now; now = m->ticks; while(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; /* * if someone is reading /dev/kprint, * put the message there. * if not and there's an attached bit mapped display, * put the message there. * * if there's a serial line being used as a console, * put the message there. */ if(kprintoq != nil && !qisclosed(kprintoq)){ if(usewrite) qwrite(kprintoq, str, n); else qiwrite(kprintoq, str, n); }else if(screenputs != nil) screenputs(str, n); if(serialoq == nil){ uartputs(str, n); return; } while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t-str; if(usewrite){ qwrite(serialoq, str, m); qwrite(serialoq, "\r\n", 2); } else { qiwrite(serialoq, str, m); qiwrite(serialoq, "\r\n", 2); } n -= m+1; str = t+1; } else { if(usewrite) qwrite(serialoq, str, n); else qiwrite(serialoq, str, n); break; } }} voidputstrn(char *str, int n){ putstrn0(str, n, 0);} int noprint; intprint(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; if(noprint) return -1; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); 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); uartputs(buf, n); splx(s); return n;} voidpanic(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; static int panicking; kprintoq = nil; /* don't try to write to /dev/kprint */ if(panicking) for(;;); panicking = 1; splhi(); strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; va_end(arg); buf[n] = '\n'; uartputs(buf, n+1); if(consdebug) (*consdebug)(); spllo(); prflush(); putstrn(buf, n+1); dumpstack(); exit(1);} void_assert(char *fmt){ panic("assert failed: %s", fmt);} intpprint(char *fmt, ...){ int n; Chan *c; va_list arg; char buf[2*PRINTSIZE]; if(up == nil || up->fgrp == nil) return 0; c = up->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; n = sprint(buf, "%s %lud: ", up->text, up->pid); va_start(arg, fmt); n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); if(waserror()) return 0; devtab[c->type]->write(c, buf, n, c->offset); poperror(); lock(c); c->offset += n; unlock(c); return n;} static voidechoscreen(char *buf, int n){ char *e, *p; char ebuf[128]; int x; p = ebuf; e = ebuf + sizeof(ebuf) - 4; while(n-- > 0){ if(p >= e){ screenputs(ebuf, p - ebuf); p = ebuf; } x = *buf++; if(x == 0x15){ *p++ = '^'; *p++ = 'U'; *p++ = '\n'; } else *p++ = x; } if(p != ebuf) screenputs(ebuf, p - ebuf);} static voidechoserialoq(char *buf, int n){ char *e, *p; char ebuf[128]; int x; p = ebuf; e = ebuf + sizeof(ebuf) - 4; while(n-- > 0){ if(p >= e){ qiwrite(serialoq, ebuf, p - ebuf); p = ebuf; } x = *buf++; if(x == '\n'){ *p++ = '\r'; *p++ = '\n'; } else if(x == 0x15){ *p++ = '^'; *p++ = 'U'; *p++ = '\n'; } else *p++ = x; } if(p != ebuf) qiwrite(serialoq, ebuf, p - ebuf);} voidecho(char *buf, int n){ static int ctrlt, pid; extern ulong etext; int x; char *e, *p; 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(); 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': if(!cpuserver) killbig(); return; case 'r': exit(0); return; } } qproduce(kbdq, buf, n); if(kbd.raw) return; if(screenputs != nil) echoscreen(buf, n); if(serialoq) echoserialoq(buf, n);} /* * Called by a uart interrupt for console input. * * turn '\r' into '\n' before putting it into the queue. */intkbdcr2nl(Queue*, int ch){ char *next; ilock(&kbd.lockputc); /* just a mutex */ if(ch == '\r' && !kbd.raw) ch = '\n'; next = kbd.iw+1; if(next >= kbd.ie) next = kbd.istage; if(next != kbd.ir){ *kbd.iw = ch; kbd.iw = next; } iunlock(&kbd.lockputc); return 0;} /* * Put character, possibly a rune, into read queue at interrupt time. * Called at interrupt time to process a character. */intkbdputc(Queue*, int ch){ int i, n; char buf[3]; Rune r; char *next; if(kbd.ir == nil) return 0; /* in case we're not inited yet */ ilock(&kbd.lockputc); /* just a mutex */ r = ch; n = runetochar(buf, &r); for(i = 0; i < n; i++){ next = kbd.iw+1; if(next >= kbd.ie) next = kbd.istage; if(next == kbd.ir) break; *kbd.iw = buf[i]; kbd.iw = next; } iunlock(&kbd.lockputc); return 0;} /* * we save up input characters till clock time to reduce * per character interrupt overhead. */static voidkbdputcclock(void){ char *iw; /* this amortizes cost of qproduce */ if(kbd.iw != kbd.ir){ iw = kbd.iw; if(iw < kbd.ir){ echo(kbd.ir, kbd.ie-kbd.ir); kbd.ir = kbd.istage; } echo(kbd.ir, iw-kbd.ir); kbd.ir = iw; }} enum{ Qdir, Qbintime, Qcons, Qconsctl, Qcputime, Qdrivers, Qkprint, Qhostdomain, Qhostowner, Qnull, Qosversion, Qpgrpid, Qpid, Qppid, Qrandom, Qreboot, Qswap, Qsysname, Qsysstat, Qtime, Quser, Qzero,Lines 1–500 of 1210. Load more
#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include <authsrv.h> void (*consdebug)(void) = nil; void (*screenputs)(char*, int) = nil; Queue* kbdq; /* unprocessed console input */ Queue* lineq; /* processed console input */ Queue* serialoq; /* serial console output */ Queue* kprintoq; /* console output, for /dev/kprint */ ulong kprintinuse; /* test and set whether /dev/kprint is open */ int iprintscreenputs = 1; static struct { QLock; int raw; /* true if we shouldn't process input */ int ctl; /* number of opens to the control file */ int x; /* index into line */ char line[1024]; /* current input line */ int count; int ctlpoff; /* a place to save up characters at interrupt time before dumping them in the queue */ Lock lockputc; char istage[512]; char *iw; char *ir; char *ie; } kbd = { .iw = kbd.istage, .ir = kbd.istage, .ie = kbd.istage + sizeof(kbd.istage), }; char *sysname; vlong fasthz; static void seedrand(void); static int readtime(ulong, char*, int); static int readbintime(char*, int); static int writetime(char*, int); static int writebintime(char*, int); enum { CMreboot, CMpanic, }; Cmdtab rebootmsg[] = { CMreboot, "reboot", 0, CMpanic, "panic", 0, }; void printinit(void) { lineq = qopen(2*1024, 0, 0, 0); if(lineq == nil) panic("printinit"); qnoblock(lineq, 1); } int consactive(void) { if(serialoq) return qlen(serialoq) > 0; return 0; } void prflush(void) { ulong now; now = m->ticks; while(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; /* * if someone is reading /dev/kprint, * put the message there. * if not and there's an attached bit mapped display, * put the message there. * * if there's a serial line being used as a console, * put the message there. */ if(kprintoq != nil && !qisclosed(kprintoq)){ if(usewrite) qwrite(kprintoq, str, n); else qiwrite(kprintoq, str, n); }else if(screenputs != nil) screenputs(str, n); if(serialoq == nil){ uartputs(str, n); return; } while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t-str; if(usewrite){ qwrite(serialoq, str, m); qwrite(serialoq, "\r\n", 2); } else { qiwrite(serialoq, str, m); qiwrite(serialoq, "\r\n", 2); } n -= m+1; str = t+1; } else { if(usewrite) qwrite(serialoq, str, n); else qiwrite(serialoq, str, n); break; } } } void putstrn(char *str, int n) { putstrn0(str, n, 0); } int noprint; int print(char *fmt, ...) { int n; va_list arg; char buf[PRINTSIZE]; if(noprint) return -1; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return 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]; static int panicking; kprintoq = nil; /* don't try to write to /dev/kprint */ if(panicking) for(;;); panicking = 1; splhi(); strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; va_end(arg); buf[n] = '\n'; uartputs(buf, n+1); if(consdebug) (*consdebug)(); spllo(); prflush(); putstrn(buf, n+1); dumpstack(); exit(1); } void _assert(char *fmt) { panic("assert failed: %s", fmt); } int pprint(char *fmt, ...) { int n; Chan *c; va_list arg; char buf[2*PRINTSIZE]; if(up == nil || up->fgrp == nil) return 0; c = up->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; n = sprint(buf, "%s %lud: ", up->text, up->pid); va_start(arg, fmt); n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); if(waserror()) return 0; devtab[c->type]->write(c, buf, n, c->offset); poperror(); lock(c); c->offset += n; unlock(c); return n; } static void echoscreen(char *buf, int n) { char *e, *p; char ebuf[128]; int x; p = ebuf; e = ebuf + sizeof(ebuf) - 4; while(n-- > 0){ if(p >= e){ screenputs(ebuf, p - ebuf); p = ebuf; } x = *buf++; if(x == 0x15){ *p++ = '^'; *p++ = 'U'; *p++ = '\n'; } else *p++ = x; } if(p != ebuf) screenputs(ebuf, p - ebuf); } static void echoserialoq(char *buf, int n) { char *e, *p; char ebuf[128]; int x; p = ebuf; e = ebuf + sizeof(ebuf) - 4; while(n-- > 0){ if(p >= e){ qiwrite(serialoq, ebuf, p - ebuf); p = ebuf; } x = *buf++; if(x == '\n'){ *p++ = '\r'; *p++ = '\n'; } else if(x == 0x15){ *p++ = '^'; *p++ = 'U'; *p++ = '\n'; } else *p++ = x; } if(p != ebuf) qiwrite(serialoq, ebuf, p - ebuf); } void echo(char *buf, int n) { static int ctrlt, pid; extern ulong etext; int x; char *e, *p; 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(); 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': if(!cpuserver) killbig(); return; case 'r': exit(0); return; } } qproduce(kbdq, buf, n); if(kbd.raw) return; if(screenputs != nil) echoscreen(buf, n); if(serialoq) echoserialoq(buf, n); } /* * Called by a uart interrupt for console input. * * turn '\r' into '\n' before putting it into the queue. */ int kbdcr2nl(Queue*, int ch) { char *next; ilock(&kbd.lockputc); /* just a mutex */ if(ch == '\r' && !kbd.raw) ch = '\n'; next = kbd.iw+1; if(next >= kbd.ie) next = kbd.istage; if(next != kbd.ir){ *kbd.iw = ch; kbd.iw = next; } iunlock(&kbd.lockputc); return 0; } /* * Put character, possibly a rune, into read queue at interrupt time. * Called at interrupt time to process a character. */ int kbdputc(Queue*, int ch) { int i, n; char buf[3]; Rune r; char *next; if(kbd.ir == nil) return 0; /* in case we're not inited yet */ ilock(&kbd.lockputc); /* just a mutex */ r = ch; n = runetochar(buf, &r); for(i = 0; i < n; i++){ next = kbd.iw+1; if(next >= kbd.ie) next = kbd.istage; if(next == kbd.ir) break; *kbd.iw = buf[i]; kbd.iw = next; } iunlock(&kbd.lockputc); return 0; } /* * we save up input characters till clock time to reduce * per character interrupt overhead. */ static void kbdputcclock(void) { char *iw; /* this amortizes cost of qproduce */ if(kbd.iw != kbd.ir){ iw = kbd.iw; if(iw < kbd.ir){ echo(kbd.ir, kbd.ie-kbd.ir); kbd.ir = kbd.istage; } echo(kbd.ir, iw-kbd.ir); kbd.ir = iw; } } enum{ Qdir, Qbintime, Qcons, Qconsctl, Qcputime, Qdrivers, Qkprint, Qhostdomain, Qhostowner, Qnull, Qosversion, Qpgrpid, Qpid, Qppid, Qrandom, Qreboot, Qswap, Qsysname, Qsysstat, Qtime, Quser, Qzero,