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

This commit is contained in:
cinap_lenrek 2017-10-20 20:31:30 +02:00
parent 29411f58cf
commit 67d9c6b2f9
3 changed files with 41 additions and 35 deletions

View file

@ -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 */

View file

@ -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;
}
}

View file

@ -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;