acme/win: fix fswrite() not assuming iounit < EVENTSIZE

This commit is contained in:
cinap_lenrek 2014-12-12 21:06:16 +01:00
parent 651fa5bd50
commit aac81cf070

View file

@ -46,10 +46,9 @@ fswrite(Req *r)
{
static Event *e[4];
Event *ep;
int i, j, ei, nb, wid, pid;
int nb, wid, pid;
Rune rune;
char *s;
char tmp[UTFmax], *t;
char *s, *se, *d, *p;
static int n, partial;
if(r->fid->file == devnew){
@ -60,58 +59,80 @@ fswrite(Req *r)
s = emalloc(r->ifcall.count+1);
memmove(s, r->ifcall.data, r->ifcall.count);
s[r->ifcall.count] = 0;
pid = strtol(s, &t, 0);
if(*t==' ')
t++;
i = newpipewin(pid, t);
pid = strtol(s, &p, 0);
if(*p==' ')
p++;
nb = newpipewin(pid, p);
free(s);
s = emalloc(32);
sprint(s, "%lud", (ulong)i);
sprint(s, "%lud", (ulong)nb);
r->fid->aux = s;
r->ofcall.count = r->ifcall.count;
respond(r, nil);
return;
}
assert(r->fid->file == devcons);
if(r->fid->file != devcons){
respond(r, "bug in fswrite");
return;
}
/* init buffer rings */
if(e[0] == nil){
for(i=0; i<nelem(e); i++){
e[i] = emalloc(sizeof(Event));
e[i]->c1 = 'S';
for(n=0; n<nelem(e); n++){
e[n] = emalloc(sizeof(Event));
e[n]->c1 = 'S';
}
}
ep = e[n];
n = (n+1)%nelem(e);
assert(r->ifcall.count <= 8192); /* is this guaranteed by lib9p? */
nb = r->ifcall.count;
memmove(ep->b+partial, r->ifcall.data, nb);
nb += partial;
ep->b[nb] = '\0';
if(strlen(ep->b) < nb){ /* nulls in data */
t = ep->b;
for(i=j=0; i<nb; i++)
if(ep->b[i] != '\0')
t[j++] = ep->b[i];
nb = j;
t[j] = '\0';
s = r->ifcall.data;
se = s + r->ifcall.count;
while((nb = (se - s)) > 0){
assert(partial >= 0);
if((partial+nb) > EVENTSIZE)
nb = EVENTSIZE - partial;
/* fill buffer */
ep = e[n % nelem(e)];
memmove(ep->b+partial, s, nb);
partial += nb;
s += nb;
/* check full runes, remove null bytes */
ep->nr = ep->nb = 0;
for(d = p = ep->b; partial > 0; partial -= wid, p += wid){
if(*p == '\0'){
wid = 1;
continue;
}
if(!fullrune(p, partial))
break;
wid = chartorune(&rune, p);
runetochar(d, &rune);
d += wid;
ep->nr++;
ep->nb += wid;
}
/* send buffer when not empty */
if(ep->nb > 0){
ep->b[ep->nb] = '\0';
sendp(win->cevent, ep);
recvp(writechan);
}
n++;
/* put partial reminder onto next buffer */
if(partial > 0){
ep = e[n % nelem(e)];
memmove(ep->b, p, partial);
}
}
ei = nb>8192? 8192 : nb;
/* process bytes into runes, transferring terminal partial runes into next buffer */
for(i=j=0; i<ei && fullrune(ep->b+i, ei-i); i+=wid,j++)
wid = chartorune(&rune, ep->b+i);
memmove(tmp, ep->b+i, nb-i);
partial = nb-i;
ep->nb = i;
ep->nr = j;
ep->b[i] = '\0';
if(i != 0){
sendp(win->cevent, ep);
recvp(writechan);
}
partial = nb-i;
memmove(e[n]->b, tmp, partial);
r->ofcall.count = r->ifcall.count;
respond(r, nil);
}