shithub: riscv

Download patch

ref: 67d9c6b2f98888dc81154b0499bbd26171f908a6
parent: 29411f58cfa62a7d05713070338d82b722364665
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Oct 20 16:31:30 EDT 2017

vt: block when sending input to host (fixes truncated paste)

--- a/sys/src/cmd/vt/cons.h
+++ b/sys/src/cmd/vt/cons.h
@@ -7,14 +7,6 @@
 };
 extern Consstate cs[];
 
-typedef struct Buf	Buf;
-struct Buf
-{
-	int	n;
-	char	*s;
-	char	b[];
-};
-
 #define	INSET	2
 #define	BUFS	32
 #define	HISTSIZ	(64*1024)	/* number of history characters */
--- a/sys/src/cmd/vt/fs.c
+++ b/sys/src/cmd/vt/fs.c
@@ -19,17 +19,16 @@
 fsreader(void*)
 {
 	Req *r, *fr;
-	Buf *b;
-	int n;
+	char *s, *p;
 
-	b = nil;
 	r = nil;
+	s = p = nil;
 	for(;;){
 		Alt a[] = {
 			{ flushreq, &fr, CHANRCV },
 			{ readreq, &r, r == nil ? CHANRCV : CHANNOP },
-			{ hc[0], &b, b == nil ? CHANRCV : CHANNOP },
-			{ nil, nil, b == nil || r == nil ? CHANEND : CHANNOBLK },
+			{ hc[0], &s, s == nil ? CHANRCV : CHANNOP },
+			{ nil, nil, s == nil || r == nil ? CHANEND : CHANNOBLK },
 		};
 		if(alt(a) == 0){
 			if(fr->oldreq == r){
@@ -38,18 +37,18 @@
 			}
 			respond(fr, nil);
 		}
-		if(b == nil || r == nil)
+		if(s == nil || r == nil)
 			continue;
+		if(p == nil)
+			p = s;
 		r->ofcall.count = 0;
-		while((n = r->ifcall.count - r->ofcall.count) > 0){
-			if(n > b->n)
-				n = b->n;
-			memmove((char*)r->ofcall.data + r->ofcall.count, b->s, n);
-			r->ofcall.count += n;
-			b->s += n, b->n -= n;
-			if(b->n <= 0){
-				free(b);
-				if((b = nbrecvp(hc[0])) == nil)
+		while(r->ifcall.count > r->ofcall.count){
+			if(*p == 0)
+				break;
+			r->ofcall.data[r->ofcall.count++] = *p++;
+			if(*p == 0){
+				free(s);
+				if((p = s = nbrecvp(hc[0])) == nil)
 					break;
 			}
 		}
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -122,6 +122,7 @@
 int	hostpid = -1;
 Biobuf	*snarffp = 0;
 Rune	*hostbuf, *hostbufp;
+char	*hostin;
 char	echo_input[BSIZE];
 char	*echop = echo_input;		/* characters to echo, after canon */
 char	sendbuf[BSIZE];	/* hope you can't type ahead more than BSIZE chars */
@@ -138,6 +139,7 @@
 void	readmenu(void);
 void	selection(void);
 void	resize(void);
+void	drawcursor(void);
 void	send_interrupt(void);
 int	alnum(int);
 void	escapedump(int,uchar *,int);
@@ -183,12 +185,17 @@
 void
 sendnchars(int n, char *p)
 {
-	Buf *b;
-
-	b = emalloc9p(sizeof(Buf)+n);
-	memmove(b->s = b->b, p, b->n = n);
-	if(nbsendp(hc[0], b) < 0)
-		free(b);
+	hostin = smprint("%.*s", n, p);
+	while(hostin != nil){
+		if(nbsendp(hc[0], hostin)){
+			hostin = nil;
+			break;
+		}
+		drawcursor();
+		waitio();
+		if(resize_flag)
+			resize();
+	}
 }
 
 static void
@@ -263,7 +270,7 @@
 	if((kc = initkeyboard("/dev/cons")) == nil)
 		sysfatal("initkeyboard failed: %r");
 
-	hc[0] = chancreate(sizeof(Buf*), 8);	/* input to host */
+	hc[0] = chancreate(sizeof(char*), 256);	/* input to host */
 	hc[1] = chancreate(sizeof(Rune*), 8);	/* output from host */
 
 	cs->raw = rflag;
@@ -405,7 +412,7 @@
 	if(cursoron == 0)
 		return;
 
-	col = (blocked || hostclosed) ? red : bordercol;
+	col = (hostin != nil || blocked || hostclosed) ? red : bordercol;
 	r = Rpt(pt(x, y), pt(x+1, y+1));
 
 	cursorsave = allocimage(display, r, screen->chan, 0, DNofill);
@@ -745,18 +752,23 @@
 void
 waitio(void)
 {
-	enum { AMOUSE, ARESIZE, AKBD, AHOST, AEND, };
+	enum { AMOUSE, ARESIZE, AKBD, AHOSTIN, AHOSTOUT, AEND, };
 	Alt a[AEND+1] = {
 		{ mc->c, &mc->Mouse, CHANRCV },
 		{ mc->resizec, nil, CHANRCV },
 		{ kc->c, &kbdchar, CHANRCV },
+		{ hc[0], &hostin, CHANSND },
 		{ hc[1], &hostbuf, CHANRCV },
 		{ nil, nil, CHANEND },
 	};
+	if(kbdchar != 0)
+		a[AKBD].op = CHANNOP;
+	if(hostin == nil)
+		a[AHOSTIN].op = CHANNOP;
 	if(blocked)
-		a[AHOST].op = CHANNOP;
+		a[AHOSTOUT].op = CHANNOP;
 	else if(hostbuf != nil)
-		a[AHOST].op = CHANNOBLK;
+		a[AHOSTOUT].op = CHANNOBLK;
 Next:
 	if(display->bufp > display->buf)
 		flushimage(display, 1);
@@ -772,7 +784,10 @@
 	case ARESIZE:
 		resize_flag = 2;
 		break;
-	case AHOST:
+	case AHOSTIN:
+		hostin = nil;
+		break;
+	case AHOSTOUT:
 		hostbufp = hostbuf;
 		if(hostbuf == nil)
 			hostclosed = 1;