diff --git a/acme/bin/source/win/fs.c b/acme/bin/source/win/fs.c index 6c41eb072..bdfe08204 100644 --- a/acme/bin/source/win/fs.c +++ b/acme/bin/source/win/fs.c @@ -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; ic1 = 'S'; + for(n=0; nc1 = '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; ib[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; ib+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); }