when resizing the screen, the text contents where lost. with the kmesg buffer, we can just re-render the text.
Unified · Split
| @@ -350,15 +350,15 @@ enum · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | struct Proc |
| 352 | 352 | { |
| 353 | − uint state; | |
| 354 | − uint mach; | |
| 353 | + uint state; | |
| 354 | + uint mach; | |
| 355 | 355 | |
| 356 | 356 | ulong pid; |
| 357 | 357 | ulong parentpid; |
| 358 | 358 | |
| 359 | 359 | Pgrp *pgrp; /* Process group for namespace */ |
| 360 | 360 | Fgrp *fgrp; /* File descriptor group */ |
| 361 | − Rgrp *rgrp; | |
| 361 | + Rgrp *rgrp; | |
| 362 | 362 | |
| 363 | 363 | Lock rlock; /* sync sleep/wakeup with postnote */ |
| 364 | 364 | Rendez *r; /* rendezvous point slept on */ |
| @@ -372,21 +372,21 @@ struct Proc · 7 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | int nerrlab; |
| 374 | 374 | Label errlab[NERR]; |
| 375 | − char user[KNAMELEN]; | |
| 375 | + char user[KNAMELEN]; | |
| 376 | 376 | char *syserrstr; /* last error from a system call, errbuf0 or 1 */ |
| 377 | 377 | char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ |
| 378 | 378 | char errbuf0[ERRMAX]; |
| 379 | 379 | char errbuf1[ERRMAX]; |
| 380 | 380 | char genbuf[128]; /* buffer used e.g. for last name element from namec */ |
| 381 | − char text[KNAMELEN]; | |
| 381 | + char text[KNAMELEN]; | |
| 382 | 382 | |
| 383 | 383 | Chan *slash; |
| 384 | 384 | Chan *dot; |
| 385 | 385 | |
| 386 | − Proc *qnext; | |
| 386 | + Proc *qnext; | |
| 387 | 387 | |
| 388 | 388 | void (*fn)(void*); |
| 389 | − void *arg; | |
| 389 | + void *arg; | |
| 390 | 390 | |
| 391 | 391 | char oproc[1024]; /* reserved for os */ |
| 392 | 392 | |
| @@ -469,6 +469,16 @@ enum · 76 unmodified lines | ||
| 469 | 469 | |
| 470 | 470 | #define DEVDOTDOT -1 |
| 471 | 471 | |
| 472 | −extern Proc *_getproc(void); | |
| 473 | −extern void _setproc(Proc*); | |
| 472 | +extern Proc *_getproc(void); | |
| 473 | +extern void _setproc(Proc*); | |
| 474 | 474 | #define up (_getproc()) |
| 475 | + | |
| 476 | +/* | |
| 477 | + * Log console output so it can be retrieved via /dev/kmesg. | |
| 478 | + * This is good for catching boot-time messages after the fact. | |
| 479 | + */ | |
| 480 | +struct { | |
| 481 | + Lock lk; | |
| 482 | + uint n; | |
| 483 | + char buf[16384]; | |
| 484 | +} kmesg; | |
| @@ -97,6 +97,35 @@ printinit(void) · 96 unmodified lines | ||
| 97 | 97 | qnoblock(kbdq, 1); |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | +static void | |
| 101 | +kmesgputs(char *str, int n) | |
| 102 | +{ | |
| 103 | + uint nn, d; | |
| 104 | + | |
| 105 | + ilock(&kmesg.lk); | |
| 106 | + /* take the tail of huge writes */ | |
| 107 | + if(n > sizeof kmesg.buf){ | |
| 108 | + d = n - sizeof kmesg.buf; | |
| 109 | + str += d; | |
| 110 | + n -= d; | |
| 111 | + } | |
| 112 | + | |
| 113 | + /* slide the buffer down to make room */ | |
| 114 | + nn = kmesg.n; | |
| 115 | + if(nn + n >= sizeof kmesg.buf){ | |
| 116 | + d = nn + n - sizeof kmesg.buf; | |
| 117 | + if(d) | |
| 118 | + memmove(kmesg.buf, kmesg.buf+d, sizeof kmesg.buf-d); | |
| 119 | + nn -= d; | |
| 120 | + } | |
| 121 | + | |
| 122 | + /* copy the data in */ | |
| 123 | + memmove(kmesg.buf+nn, str, n); | |
| 124 | + nn += n; | |
| 125 | + kmesg.n = nn; | |
| 126 | + iunlock(&kmesg.lk); | |
| 127 | +} | |
| 128 | + | |
| 100 | 129 | /* |
| 101 | 130 | * Print a string on the console. Convert \n to \r\n for serial |
| 102 | 131 | * line consoles. Locking of the queues is left up to the screen |
| @@ -106,6 +135,11 @@ printinit(void) · 3 unmodified lines | ||
| 106 | 135 | static void |
| 107 | 136 | putstrn0(char *str, int n, int usewrite) |
| 108 | 137 | { |
| 138 | + /* | |
| 139 | + * how many different output devices do we need? | |
| 140 | + */ | |
| 141 | + kmesgputs(str, n); | |
| 142 | + | |
| 109 | 143 | /* |
| 110 | 144 | * if someone is reading /dev/kprint, |
| 111 | 145 | * put the message there. |
| @@ -298,6 +332,7 @@ enum{ · 186 unmodified lines | ||
| 298 | 332 | Qconsctl, |
| 299 | 333 | Qcputime, |
| 300 | 334 | Qdrivers, |
| 335 | + Qkmesg, | |
| 301 | 336 | Qkprint, |
| 302 | 337 | Qhostdomain, |
| 303 | 338 | Qhostowner, |
| @@ -331,7 +366,8 @@ static Dirtab consdir[]={ · 27 unmodified lines | ||
| 331 | 366 | "drivers", {Qdrivers}, 0, 0444, |
| 332 | 367 | "hostdomain", {Qhostdomain}, DOMLEN, 0664, |
| 333 | 368 | "hostowner", {Qhostowner}, 0, 0664, |
| 334 | − "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, | |
| 369 | + "kmesg", {Qkmesg}, 0, 0440, | |
| 370 | + "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, | |
| 335 | 371 | "null", {Qnull}, 0, 0666, |
| 336 | 372 | "osversion", {Qosversion}, 0, 0444, |
| 337 | 373 | "pgrpid", {Qpgrpid}, NUMSIZE, 0444, |
| @@ -554,6 +590,22 @@ consread(Chan *c, void *buf, long n, vlong off) · 216 unmodified lines | ||
| 554 | 590 | case Qcputime: |
| 555 | 591 | return 0; |
| 556 | 592 | |
| 593 | + case Qkmesg: | |
| 594 | + /* | |
| 595 | + * This is unlocked to avoid tying up a process | |
| 596 | + * that's writing to the buffer. kmesg.n never | |
| 597 | + * gets smaller, so worst case the reader will | |
| 598 | + * see a slurred buffer. | |
| 599 | + */ | |
| 600 | + if(off >= kmesg.n) | |
| 601 | + n = 0; | |
| 602 | + else{ | |
| 603 | + if(off+n > kmesg.n) | |
| 604 | + n = kmesg.n - off; | |
| 605 | + memmove(buf, kmesg.buf+off, n); | |
| 606 | + } | |
| 607 | + return n; | |
| 608 | + | |
| 557 | 609 | case Qkprint: |
| 558 | 610 | return qread(kprintoq, buf, n); |
| 559 | 611 | |
| @@ -8,28 +8,18 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <memdraw.h> |
| 9 | 9 | #include "screen.h" |
| 10 | 10 | |
| 11 | −#define MINX 8 | |
| 12 | −#define Backgnd 0xFF /* white */ | |
| 11 | +extern Memimage *gscreen; | |
| 13 | 12 | |
| 14 | − Memsubfont *memdefont; | |
| 15 | − | |
| 16 | −struct{ | |
| 17 | − Point pos; | |
| 18 | − int bwid; | |
| 19 | −}out; | |
| 20 | − | |
| 21 | −Lock screenlock; | |
| 22 | − | |
| 23 | −Memimage *conscol; | |
| 24 | −Memimage *back; | |
| 25 | −extern Memimage *gscreen; | |
| 26 | − | |
| 27 | −static Rectangle flushr; | |
| 28 | −static Rectangle window; | |
| 29 | −static Point curpos; | |
| 30 | −static int h; | |
| 31 | −static void termscreenputs(char*, int); | |
| 13 | +static Memsubfont *memdefont; | |
| 14 | +static Lock screenlock; | |
| 15 | +static Memimage *conscol; | |
| 16 | +static Memimage *back; | |
| 17 | +static Rectangle flushr; | |
| 18 | +static Rectangle window; | |
| 19 | +static Point curpos; | |
| 20 | +static int h; | |
| 32 | 21 | |
| 22 | +static void termscreenputs(char*, int); | |
| 33 | 23 | |
| 34 | 24 | static void |
| 35 | 25 | screenflush(void) |
| @@ -84,6 +74,8 @@ screenwin(void) · 48 unmodified lines | ||
| 84 | 74 | window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; |
| 85 | 75 | flushmemscreen(gscreen->r); |
| 86 | 76 | qunlock(&drawlock); |
| 77 | + | |
| 78 | + termscreenputs(kmesg.buf, kmesg.n); | |
| 87 | 79 | } |
| 88 | 80 | |
| 89 | 81 | static struct { |
| @@ -137,9 +129,6 @@ void · 47 unmodified lines | ||
| 137 | 129 | terminit(void) |
| 138 | 130 | { |
| 139 | 131 | memdefont = getmemdefont(); |
| 140 | − out.pos.x = MINX; | |
| 141 | − out.pos.y = 0; | |
| 142 | − out.bwid = memdefont->info[' '].width; | |
| 143 | 132 | screenwin(); |
| 144 | 133 | screenputs = termscreenputs; |
| 145 | 134 | kproc("resize", resizeproc, nil); |