From 67d9c6b2f98888dc81154b0499bbd26171f908a6 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 20 Oct 2017 20:31:30 +0200 Subject: [PATCH] vt: block when sending input to host (fixes truncated paste) --- sys/src/cmd/vt/cons.h | 8 -------- sys/src/cmd/vt/fs.c | 29 ++++++++++++++--------------- sys/src/cmd/vt/main.c | 39 +++++++++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/sys/src/cmd/vt/cons.h b/sys/src/cmd/vt/cons.h index c08df6088..76102b745 100644 --- a/sys/src/cmd/vt/cons.h +++ b/sys/src/cmd/vt/cons.h @@ -7,14 +7,6 @@ struct Consstate{ }; 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 */ diff --git a/sys/src/cmd/vt/fs.c b/sys/src/cmd/vt/fs.c index 1c2b5ca23..bf66972b4 100644 --- a/sys/src/cmd/vt/fs.c +++ b/sys/src/cmd/vt/fs.c @@ -19,17 +19,16 @@ static void 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 @@ fsreader(void*) } 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; } } diff --git a/sys/src/cmd/vt/main.c b/sys/src/cmd/vt/main.c index 969f5f8da..528191bf4 100644 --- a/sys/src/cmd/vt/main.c +++ b/sys/src/cmd/vt/main.c @@ -122,6 +122,7 @@ int logfd = -1; 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 bigscroll(void); 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 @@ send_interrupt(void) 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 @@ threadmain(int argc, char **argv) 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 @@ drawcursor(void) 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 @@ waitchar(void) 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 @@ Next: case ARESIZE: resize_flag = 2; break; - case AHOST: + case AHOSTIN: + hostin = nil; + break; + case AHOSTOUT: hostbufp = hostbuf; if(hostbuf == nil) hostclosed = 1;