]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/rio/xfid.c
rio: fix bug causing short reads of wctl files
[plan9front.git] / sys / src / cmd / rio / xfid.c
index a66c94d586011abf44a41e2ea0c3b02c1495cfaa..b8e4be84a43f525fd8d00e0d69d6d9bad6e56049 100644 (file)
@@ -179,6 +179,7 @@ xfidattach(Xfid *x)
        qlock(&all);
        w = nil;
        err = Eunkid;
+       dir = nil;
        newlymade = FALSE;
        hideit = 0;
        scrollit = scrolling;
@@ -209,7 +210,7 @@ xfidattach(Xfid *x)
                        if(i){
                                if(pid == 0)
                                        pid = -1;       /* make sure we don't pop a shell! - UGH */
-                               w = new(i, hideit, scrollit, pid, nil, nil, nil);
+                               w = new(i, hideit, scrollit, pid, dir, nil, nil);
                                newlymade = TRUE;
                        }else
                                err = Ewindow;
@@ -249,6 +250,10 @@ xfidopen(Xfid *x)
                return;
        }
        switch(FILE(x->f->qid)){
+       case Qtext:
+               if(x->mode&OTRUNC)
+                       wsendctlmesg(w, Truncate, ZR, nil);
+               break;
        case Qconsctl:
                if(w->ctlopen){
                        filsysrespond(x->fs, x, &t, Einuse);
@@ -256,12 +261,6 @@ xfidopen(Xfid *x)
                }
                w->ctlopen = TRUE;
                break;
-       case Qkbdin:
-               if(w != wkeyboard){
-                       filsysrespond(x->fs, x, &t, Eperm);
-                       return;
-               }
-               break;
        case Qkbd:
                if(w->kbdopen){
                        filsysrespond(x->fs, x, &t, Einuse);
@@ -391,6 +390,7 @@ xfidwrite(Xfid *x)
        x->data[cnt] = 0;
        switch(qid){
        case Qcons:
+       case Qtext:
                alts[CWdata].c = w->conswrite;
                alts[CWdata].v = &cwm;
                alts[CWdata].op = CHANRCV;
@@ -483,7 +483,7 @@ xfidwrite(Xfid *x)
                        memmove(w->cursor.clr, x->data+2*4, 2*2*16);
                        w->cursorp = &w->cursor;
                }
-               wsetcursor(w, !sweeping);
+               wsetcursor(w, TRUE);
                break;
 
        case Qlabel:
@@ -560,10 +560,6 @@ xfidwrite(Xfid *x)
                w->dir = cleanname(p);
                break;
 
-       case Qkbdin:
-               keyboardsend(x->data, cnt);
-               break;
-
        case Qwctl:
                if(writewctl(x, err) < 0){
                        filsysrespond(x->fs, x, &fc, err);
@@ -623,13 +619,9 @@ xfidread(Xfid *x)
        Channel *c1, *c2;       /* chan (tuple(char*, int)) */
        Consreadmesg crm;
        Mousereadmesg mrm;
-       Consreadmesg cwrm;
-       Kbdreadmesg krm;
        Stringpair pair;
-       enum { CRdata, CRgone, CRflush, NCR };
-       enum { MRdata, MRgone, MRflush, NMR };
-       enum { WCRdata, WCRgone, WCRflush, NWCR };
-       Alt alts[NCR+1];
+       enum { Adata, Agone, Aflush, Aend };
+       Alt alts[Aend+1];
 
        w = x->f->w;
        if(w->deleted){
@@ -640,38 +632,51 @@ xfidread(Xfid *x)
        off = x->offset;
        cnt = x->count;
        switch(qid){
+       case Qwctl:
+               if(cnt < 4*12){
+                       filsysrespond(x->fs, x, &fc, Etooshort);
+                       return;
+               }
+               alts[Adata].c = w->wctlread;
+               goto Consmesg;
+
+       case Qkbd:
+               alts[Adata].c = w->kbdread;
+               goto Consmesg;
+
        case Qcons:
-               alts[CRdata].c = w->consread;
-               alts[CRdata].v = &crm;
-               alts[CRdata].op = CHANRCV;
-               alts[CRgone].c = w->gone;
-               alts[CRgone].v = nil;
-               alts[CRgone].op = CHANRCV;
-               alts[CRflush].c = x->flushc;
-               alts[CRflush].v = nil;
-               alts[CRflush].op = CHANRCV;
-               alts[NCR].op = CHANEND;
+               alts[Adata].c = w->consread;
+
+       Consmesg:
+               alts[Adata].v = &crm;
+               alts[Adata].op = CHANRCV;
+               alts[Agone].c = w->gone;
+               alts[Agone].v = nil;
+               alts[Agone].op = CHANRCV;
+               alts[Aflush].c = x->flushc;
+               alts[Aflush].v = nil;
+               alts[Aflush].op = CHANRCV;
+               alts[Aend].op = CHANEND;
 
                switch(alt(alts)){
-               case CRdata:
+               case Adata:
                        break;
-               case CRgone:
+               case Agone:
                        filsysrespond(x->fs, x, &fc, Edeleted);
                        return;
-               case CRflush:
+               case Aflush:
                        filsyscancel(x);
                        return;
                }
-
                c1 = crm.c1;
                c2 = crm.c2;
-               t = malloc(cnt+UTFmax+1);       /* room to unpack partial rune plus */
+               pair.ns = cnt+UTFmax+1; /* room for partial rune and null byte */
+               t = emalloc(pair.ns);
                pair.s = t;
-               pair.ns = cnt;
                send(c1, &pair);
                recv(c2, &pair);
                fc.data = pair.s;
-               fc.count = pair.ns;
+               fc.count = min(cnt, pair.ns);
                filsysrespond(x->fs, x, &fc, nil);
                free(t);
                break;
@@ -688,24 +693,24 @@ xfidread(Xfid *x)
                break;
 
        case Qmouse:
-               alts[MRdata].c = w->mouseread;
-               alts[MRdata].v = &mrm;
-               alts[MRdata].op = CHANRCV;
-               alts[MRgone].c = w->gone;
-               alts[MRgone].v = nil;
-               alts[MRgone].op = CHANRCV;
-               alts[MRflush].c = x->flushc;
-               alts[MRflush].v = nil;
-               alts[MRflush].op = CHANRCV;
-               alts[NMR].op = CHANEND;
+               alts[Adata].c = w->mouseread;
+               alts[Adata].v = &mrm;
+               alts[Adata].op = CHANRCV;
+               alts[Agone].c = w->gone;
+               alts[Agone].v = nil;
+               alts[Agone].op = CHANRCV;
+               alts[Aflush].c = x->flushc;
+               alts[Aflush].v = nil;
+               alts[Aflush].op = CHANRCV;
+               alts[Aend].op = CHANEND;
 
                switch(alt(alts)){
-               case MRdata:
+               case Adata:
                        break;
-               case MRgone:
+               case Agone:
                        filsysrespond(x->fs, x, &fc, Edeleted);
                        return;
-               case MRflush:
+               case Aflush:
                        filsyscancel(x);
                        return;
                }
@@ -721,36 +726,6 @@ xfidread(Xfid *x)
                filsysrespond(x->fs, x, &fc, nil);
                break;
 
-       case Qkbd:
-               alts[MRdata].c = w->kbdread;
-               alts[MRdata].v = &krm;
-               alts[MRdata].op = CHANRCV;
-               alts[MRgone].c = w->gone;
-               alts[MRgone].v = nil;
-               alts[MRgone].op = CHANRCV;
-               alts[MRflush].c = x->flushc;
-               alts[MRflush].v = nil;
-               alts[MRflush].op = CHANRCV;
-               alts[NMR].op = CHANEND;
-
-               switch(alt(alts)){
-               case MRdata:
-                       break;
-               case MRgone:
-                       filsysrespond(x->fs, x, &fc, Edeleted);
-                       return;
-               case MRflush:
-                       filsyscancel(x);
-                       return;
-               }
-
-               t = recvp(krm.ck);
-               fc.data = t;
-               fc.count = strlen(t)+1;
-               filsysrespond(x->fs, x, &fc, nil);
-               free(t);
-               break;
-
        case Qcursor:
                filsysrespond(x->fs, x, &fc, "cursor read not implemented");
                break;
@@ -805,11 +780,11 @@ xfidread(Xfid *x)
 
        case Qwindow:
                i = w->i;
-               r = w->screenr;
-               if(i == nil || Dx(r)<=0){
+               if(i == nil){
                        filsysrespond(x->fs, x, &fc, Enowindow);
                        return;
                }
+               r = i->r;
                goto caseImage;
 
        case Qscreen:
@@ -842,49 +817,6 @@ xfidread(Xfid *x)
                free(t);
                return;
 
-       case Qwctl:     /* read returns rectangle, hangs if not resized */
-               if(cnt < 4*12){
-                       filsysrespond(x->fs, x, &fc, Etooshort);
-                       break;
-               }
-
-               alts[WCRdata].c = w->wctlread;
-               alts[WCRdata].v = &cwrm;
-               alts[WCRdata].op = CHANRCV;
-               alts[WCRgone].c = w->gone;
-               alts[WCRgone].v = nil;
-               alts[WCRgone].op = CHANRCV;
-               alts[WCRflush].c = x->flushc;
-               alts[WCRflush].v = nil;
-               alts[WCRflush].op = CHANRCV;
-               alts[NWCR].op = CHANEND;
-
-               switch(alt(alts)){
-               case WCRdata:
-                       break;
-               case WCRgone:
-                       filsysrespond(x->fs, x, &fc, Edeleted);
-                       return;
-               case WCRflush:
-                       filsyscancel(x);
-                       return;
-               }
-
-               c1 = cwrm.c1;
-               c2 = cwrm.c2;
-               t = malloc(cnt+1);      /* be sure to have room for NUL */
-               pair.s = t;
-               pair.ns = cnt+1;
-               send(c1, &pair);
-               recv(c2, &pair);
-               fc.data = pair.s;
-               if(pair.ns > cnt)
-                       pair.ns = cnt;
-               fc.count = pair.ns;
-               filsysrespond(x->fs, x, &fc, nil);
-               free(t);
-               break;
-
        default:
                fprint(2, "unknown qid %d in read\n", qid);
                snprint(buf, sizeof(buf), "unknown qid in read");