ref: bc76055c7e37f1cd087a6d274eb56a41b2fc25a7
parent: fee6fddeb6c78274abc9b2cffc9ce07d336ea8a1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 25 23:46:59 EST 2017
devcons: add #c/kmesg, redraw kmesg buffer after resize when resizing the screen, the text contents where lost. with the kmesg buffer, we can just re-render the text.
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -350,8 +350,8 @@
struct Proc
{
- uint state;
- uint mach;
+ uint state;
+ uint mach;
ulong pid;
ulong parentpid;
@@ -358,7 +358,7 @@
Pgrp *pgrp; /* Process group for namespace */
Fgrp *fgrp; /* File descriptor group */
- Rgrp *rgrp;
+ Rgrp *rgrp;
Lock rlock; /* sync sleep/wakeup with postnote */
Rendez *r; /* rendezvous point slept on */
@@ -372,21 +372,21 @@
int nerrlab;
Label errlab[NERR];
- char user[KNAMELEN];
+ char user[KNAMELEN];
char *syserrstr; /* last error from a system call, errbuf0 or 1 */
char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */
char errbuf0[ERRMAX];
char errbuf1[ERRMAX];
char genbuf[128]; /* buffer used e.g. for last name element from namec */
- char text[KNAMELEN];
+ char text[KNAMELEN];
Chan *slash;
Chan *dot;
- Proc *qnext;
+ Proc *qnext;
void (*fn)(void*);
- void *arg;
+ void *arg;
char oproc[1024]; /* reserved for os */
@@ -469,6 +469,16 @@
#define DEVDOTDOT -1
-extern Proc *_getproc(void);
-extern void _setproc(Proc*);
+extern Proc *_getproc(void);
+extern void _setproc(Proc*);
#define up (_getproc())
+
+/*
+ * Log console output so it can be retrieved via /dev/kmesg.
+ * This is good for catching boot-time messages after the fact.
+ */
+struct {
+ Lock lk;
+ uint n;
+ char buf[16384];
+} kmesg;
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -97,6 +97,35 @@
qnoblock(kbdq, 1);
}
+static void
+kmesgputs(char *str, int n)
+{
+ uint nn, d;
+
+ ilock(&kmesg.lk);
+ /* take the tail of huge writes */
+ if(n > sizeof kmesg.buf){
+ d = n - sizeof kmesg.buf;
+ str += d;
+ n -= d;
+ }
+
+ /* slide the buffer down to make room */
+ nn = kmesg.n;
+ if(nn + n >= sizeof kmesg.buf){
+ d = nn + n - sizeof kmesg.buf;
+ if(d)
+ memmove(kmesg.buf, kmesg.buf+d, sizeof kmesg.buf-d);
+ nn -= d;
+ }
+
+ /* copy the data in */
+ memmove(kmesg.buf+nn, str, n);
+ nn += n;
+ kmesg.n = nn;
+ iunlock(&kmesg.lk);
+}
+
/*
* 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
@@ -107,6 +136,11 @@
putstrn0(char *str, int n, int usewrite)
{
/*
+ * how many different output devices do we need?
+ */
+ kmesgputs(str, n);
+
+ /*
* if someone is reading /dev/kprint,
* put the message there.
* if not and there's an attached bit mapped display,
@@ -298,6 +332,7 @@
Qconsctl,
Qcputime,
Qdrivers,
+ Qkmesg,
Qkprint,
Qhostdomain,
Qhostowner,
@@ -331,7 +366,8 @@
"drivers", {Qdrivers}, 0, 0444,
"hostdomain", {Qhostdomain}, DOMLEN, 0664,
"hostowner", {Qhostowner}, 0, 0664,
- "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440,
+ "kmesg", {Qkmesg}, 0, 0440,
+ "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440,
"null", {Qnull}, 0, 0666,
"osversion", {Qosversion}, 0, 0444,
"pgrpid", {Qpgrpid}, NUMSIZE, 0444,
@@ -554,6 +590,22 @@
case Qcputime:
return 0;
+ case Qkmesg:
+ /*
+ * This is unlocked to avoid tying up a process
+ * that's writing to the buffer. kmesg.n never
+ * gets smaller, so worst case the reader will
+ * see a slurred buffer.
+ */
+ if(off >= kmesg.n)
+ n = 0;
+ else{
+ if(off+n > kmesg.n)
+ n = kmesg.n - off;
+ memmove(buf, kmesg.buf+off, n);
+ }
+ return n;
+
case Qkprint:
return qread(kprintoq, buf, n);
--- a/kern/term.c
+++ b/kern/term.c
@@ -8,29 +8,19 @@
#include <memdraw.h>
#include "screen.h"
-#define MINX 8
-#define Backgnd 0xFF /* white */
+extern Memimage *gscreen;
- Memsubfont *memdefont;
-
-struct{
- Point pos;
- int bwid;
-}out;
+static Memsubfont *memdefont;
+static Lock screenlock;
+static Memimage *conscol;
+static Memimage *back;
+static Rectangle flushr;
+static Rectangle window;
+static Point curpos;
+static int h;
-Lock screenlock;
+static void termscreenputs(char*, int);
-Memimage *conscol;
-Memimage *back;
-extern Memimage *gscreen;
-
-static Rectangle flushr;
-static Rectangle window;
-static Point curpos;
-static int h;
-static void termscreenputs(char*, int);
-
-
static void
screenflush(void)
{
@@ -84,6 +74,8 @@
window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
flushmemscreen(gscreen->r);
qunlock(&drawlock);
+
+ termscreenputs(kmesg.buf, kmesg.n);
}
static struct {
@@ -137,9 +129,6 @@
terminit(void)
{
memdefont = getmemdefont();
- out.pos.x = MINX;
- out.pos.y = 0;
- out.bwid = memdefont->info[' '].width;
screenwin();
screenputs = termscreenputs;
kproc("resize", resizeproc, nil);