ref: 169db43ad91d6873a3ba3cd1396aaaf96e9d4dc5
parent: 00334c0407e27921754d6ccd77d08045c2fa7254
parent: aac81cf0701330fff4ff83fc72e9200dc4b1a60c
author: cinap_lenrek <[email protected]>
date: Fri Dec 12 16:07:44 EST 2014
merge
--- a/acme/bin/source/win/fs.c
+++ b/acme/bin/source/win/fs.c
@@ -46,10 +46,9 @@
{
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,13 +59,13 @@
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);
@@ -73,45 +72,67 @@
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);
}