waserror() audit
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 18 Jan 2014 05:35:43 +0000 (21:35 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 18 Jan 2014 05:35:43 +0000 (21:35 -0800)
Our waserrors in the error case need a poperror or nexterror.  This
isn't how plan9 works.

This was rather painful.  Enough so that perhaps we should have changed
our ways.  Maybe next time we port a plan9 derivative.

I also dealt with the weird errstr shit in namec the same way I did with
nxm: commenting it out.  I found that (back then) to make namec harder
to debug.  We'll see.

21 files changed:
kern/arch/x86/vmx.c
kern/drivers/dev/cons.c
kern/drivers/dev/dev.c
kern/drivers/dev/mnt.c
kern/drivers/dev/vm.c
kern/src/net/arp.c
kern/src/net/devip.c
kern/src/net/ethermedium.c
kern/src/net/ip.c
kern/src/net/ipifc.c
kern/src/net/iproute.c
kern/src/net/ipv6.c
kern/src/net/loopbackmedium.c
kern/src/net/netdevmedium.c
kern/src/net/netlog.c
kern/src/net/tcp.c
kern/src/ns/chan.c
kern/src/ns/parse.c
kern/src/ns/qio.c
kern/src/ns/random.c
kern/src/ns/sysfile.c

index 0a86a7b..76daa4d 100644 (file)
@@ -1566,6 +1566,7 @@ int vmx_create_vcpu(struct litevm *litevm, int n)
        __vcpu_load(vcpu);
 
        printk("PAST vcpu_load\n");
+       #warning unmatched waserror!
        if (waserror()){
                /* we really need to fix waserror() */
                poperror();
index 60d8d51..af87be2 100644 (file)
@@ -133,6 +133,7 @@ putstrn0(char *str, int n, int usewrite)
        int m;
        char *t;
        char buf[PRINTSIZE+2];
+       ERRSTACK(1);
 
        /*
         *  if kprint is open, put the message there, otherwise
@@ -335,7 +336,7 @@ sysfatal(char *fmt, ...)
 int
 pprint(char *fmt, ...)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int n;
        struct chan *c;
        Osenv *o;
@@ -361,6 +362,7 @@ pprint(char *fmt, ...)
 
        if(waserror()) {
                printd("%s", buf);
+               poperror();
                return 0;
        }
        devtab[c->type]->write(c, buf, n, c->offset);
@@ -864,7 +866,7 @@ void logbuf(int c)
 static long
 consread(struct chan *c, void *buf, long n, int64_t offset)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int l;
 
        int ch, eol, i;
@@ -1028,6 +1030,7 @@ consread(struct chan *c, void *buf, long n, int64_t offset)
 static long
 conswrite(struct chan *c, void *va, long n, int64_t offset)
 {
+       ERRSTACK(1);
        int64_t t;
        long l, bp;
        char *a = va;
index 2fadca2..f1a7661 100644 (file)
@@ -142,7 +142,7 @@ devwalk(struct chan *c,
        struct chan *nc, char **name, int nname,
        struct dirtab *tab, int ntab, Devgen *gen)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i, j;
        volatile int alloc; /* to keep waserror from optimizing this out */
        struct walkqid *wq;
@@ -159,6 +159,7 @@ devwalk(struct chan *c,
                if(alloc && wq->clone!=NULL)
                        cclose(wq->clone);
                kfree(wq);
+               poperror();
                return NULL;
        }
        if(nc == NULL){
@@ -372,7 +373,7 @@ devcreate(struct chan*c, char *unused_char_p_t, int unused_int, uint32_t u)
 struct block*
 devbread(struct chan *c, long n, uint32_t offset)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct block *bp;
 
        bp = allocb(n);
@@ -390,7 +391,7 @@ devbread(struct chan *c, long n, uint32_t offset)
 long
 devbwrite(struct chan *c, struct block *bp, uint32_t offset)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        long n;
 
        if(waserror()) {
index 2ccb256..33d0f09 100644 (file)
@@ -106,7 +106,7 @@ mntinit(void)
 long
 mntversion(struct chan *c, char *version, int msize, int returnlen)
 {
-       ERRSTACK(4);
+       ERRSTACK(2);
        struct fcall f;
        uint8_t *msg;
        struct mnt *m;
@@ -410,6 +410,7 @@ mntwalk(struct chan *c, struct chan *nc, char **name, int nname)
                if(alloc && wq->clone!=NULL)
                        cclose(wq->clone);
                kfree(wq);
+               poperror();
                return NULL;
        }
 
@@ -476,7 +477,7 @@ mntwalk(struct chan *c, struct chan *nc, char **name, int nname)
 static int
 mntstat(struct chan *c, uint8_t *dp, int n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct mnt *m;
        struct mntrpc *r;
 
@@ -510,7 +511,7 @@ mntstat(struct chan *c, uint8_t *dp, int n)
 static struct chan*
 mntopencreate(int type, struct chan *c, char *name, int omode, uint32_t perm)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct mnt *m;
        struct mntrpc *r;
 
@@ -560,7 +561,7 @@ mntcreate(struct chan *c, char *name, int omode, uint32_t perm)
 static void
 mntclunk(struct chan *c, int t)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct mnt *m;
        struct mntrpc *r;
 
@@ -631,7 +632,7 @@ mntremove(struct chan *c)
 static int
 mntwstat(struct chan *c, uint8_t *dp, int n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct mnt *m;
        struct mntrpc *r;
 
@@ -703,7 +704,7 @@ mntwrite(struct chan *c, void *buf, long n, int64_t off)
 long
 mntrdwr(int type, struct chan *c, void *buf, long n, int64_t off)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct mnt *m;
        struct mntrpc *r;       /* TO DO: volatile struct { Mntrpc *r; } r; */
        char *uba;
@@ -790,7 +791,7 @@ mountrpc(struct mnt *m, struct mntrpc *r)
 void
 mountio(struct mnt *m, struct mntrpc *r)
 {
-       ERRSTACK(4);
+       ERRSTACK(1);
        int n;
 
        while(waserror()) {
@@ -801,6 +802,8 @@ mountio(struct mnt *m, struct mntrpc *r)
                        nexterror();
                }
                r = mntflushalloc(r, m->msize);
+               /* need one for every waserror call (so this plus one outside) */
+               poperror();
        }
 
        spin_lock(&m->lock);
index a7ba714..20fa35e 100644 (file)
@@ -269,7 +269,7 @@ static int vmstat(struct chan *c, uint8_t *db, int n)
 static struct chan *vmopen(struct chan *c, int omode)
 {
        print_func_entry();
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct vm *v = QID2VM(c->qid);
        printk("vmopen: v is %p\n", v);
        if (waserror()){
@@ -316,6 +316,7 @@ static struct chan *vmopen(struct chan *c, int omode)
        /* Assumes c is unique (can't be closed concurrently */
        c->flag |= COPEN;
        c->offset = 0;
+       poperror();
        print_func_exit();
        return c;
 }
index 02b4afd..8171202 100644 (file)
@@ -685,8 +685,9 @@ rxmitproc(void *v)
        //print("arp rxmitproc started\n");
        if(waserror()){
                arp->rxmitp = 0;
-#warning "pexit"
-               //pexit("hangup", 1);
+               poperror();
+               warn("arp rxmit ktask exited");
+               return;
        }
        for(;;){
                wakeupat = rxmitsols(arp);
@@ -695,5 +696,6 @@ rxmitproc(void *v)
                else if(wakeupat > ReTransTimer/4) 
                        udelay_sched(wakeupat * 1000); 
        }
+       poperror();
 }
 
index d76a990..77cd1db 100644 (file)
@@ -953,7 +953,7 @@ connected(void* a)
 static void
 connectctlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char *p;
 
        if(c->state != 0)
@@ -1006,7 +1006,7 @@ announced(void* a)
 static void
 announcectlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char *p;
 
        if(c->state != 0)
@@ -1080,7 +1080,7 @@ ttlctlmsg(struct conv *c, struct cmdbuf *cb)
 static long
 ipwrite(struct chan* ch, void *v, long n, int64_t off)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct conv *c;
        struct Proto *x;
        char *p;
index 484d4df..88d3399 100644 (file)
@@ -133,7 +133,7 @@ static char *nbmsg = "nonblocking";
 static void
 etherbind(struct Ipifc *ifc, int argc, char **argv)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *mchan4, *cchan4, *achan, *mchan6, *cchan6;
        char addr[Maxpath];     //char addr[2*KNAMELEN];
        char dir[Maxpath];      //char dir[2*KNAMELEN];
@@ -371,8 +371,9 @@ etherread4(void *a)
        er->read4p = current;   /* hide identity under a rock for unbind */
        if(waserror()){
                er->read4p = 0;
-#warning "pexit"
-               //      pexit("hangup", 1);
+               poperror();
+               warn("etherread4 returns, probably unexpectedly\n");
+               return;
        }
        for(;;){
                bp = devtab[er->mchan4->type]->bread(er->mchan4, ifc->maxtu, 0);
@@ -393,6 +394,7 @@ etherread4(void *a)
                runlock(&ifc->rwlock);
                poperror();
        }
+       poperror();
 }
 
 
@@ -412,7 +414,9 @@ etherread6(void *a)
        er->read6p = current;   /* hide identity under a rock for unbind */
        if(waserror()){
                er->read6p = 0;
-               //      pexit("hangup", 1);
+               warn("etherread6 returns, probably unexpectedly\n");
+               poperror();
+               return;
        }
        for(;;){
                bp = devtab[er->mchan6->type]->bread(er->mchan6, ifc->maxtu, 0);
@@ -433,6 +437,7 @@ etherread6(void *a)
                runlock(&ifc->rwlock);
                poperror();
        }
+       poperror();
 }
 
 static void
@@ -715,17 +720,20 @@ recvarp(struct Ipifc *ifc)
 static void
 recvarpproc(void *v)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct Ipifc *ifc = v;
        Etherrock *er = ifc->arg;
 
        er->arpp = current;
        if(waserror()){
                er->arpp = 0;
-               //      pexit("hangup", 1);
+               warn("recvarpproc returns, probably unexpectedly\n");
+               poperror();
+               return;
        }
        for(;;)
                recvarp(ifc);
+       poperror();
 }
 
 static int
index c1efd51..aef3e3d 100644 (file)
@@ -246,7 +246,7 @@ int
 ipoput4(struct Fs *f,
        struct block *bp, int gating, int ttl, int tos, struct conv *c)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct Ipifc *ifc;
        uint8_t *gate;
        uint32_t fragoff;
index 02e681f..7797c71 100644 (file)
@@ -113,7 +113,7 @@ ipfindmedium(char *name)
 static char*
 ipifcbind(struct conv *c, char **argv, int argc)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct Ipifc *ifc;
        struct medium *m;
 
@@ -184,7 +184,7 @@ ipifcbind(struct conv *c, char **argv, int argc)
 static char*
 ipifcunbind(struct Ipifc *ifc)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char *err;
 
        if(waserror()){
@@ -295,7 +295,7 @@ ipifcinuse(struct conv *c)
 static void
 ipifckick(void *x)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct conv *c = x;
        struct block *bp;
        struct Ipifc *ifc;
@@ -692,7 +692,7 @@ ipifcremroute(struct Fs *f, int vers, uint8_t *addr, uint8_t *mask)
 static char*
 ipifcconnect(struct conv* c, char **argv, int argc)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char *err;
        struct Ipifc *ifc;
 
@@ -1483,7 +1483,7 @@ ipisbm(uint8_t *ip)
 void
 ipifcaddmulti(struct conv *c, uint8_t *ma, uint8_t *ia)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct Ipifc *ifc;
        struct Iplifc *lifc;
        struct conv **p;
@@ -1526,7 +1526,7 @@ ipifcaddmulti(struct conv *c, uint8_t *ma, uint8_t *ia)
 void
 ipifcremmulti(struct conv *c, uint8_t *ma, uint8_t *ia)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct Ipmulti *multi, **l;
        struct Iplifc *lifc;
        struct conv **p;
index 5068639..61746de 100644 (file)
@@ -799,7 +799,7 @@ routeflush(struct Fs *f, struct route *r, char *tag)
 long
 routewrite(struct Fs *f, struct chan *c, char *p, int n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int h, changed;
        char *tag;
        struct cmdbuf *cb;
index 7e202f9..cedbe48 100644 (file)
@@ -152,7 +152,7 @@ int
 ipoput6(struct Fs *f,
        struct block *bp, int gating, int ttl, int tos, struct conv *c)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int tentative;
        struct Ipifc *ifc;
        uint8_t *gate, nexthdr;
index 2009f77..69e3a9f 100644 (file)
@@ -88,9 +88,9 @@ loopbackread(void *a)
        lb->readp = current;    /* hide identity under a rock for unbind */
        if(waserror()){
                lb->readp = 0;
-               /* kill the proc. */
-#warning "pexit"
-//             pexit("hangup", 1);
+               warn("loopbackread exits unexpectedly");
+               return;
+               poperror();
        }
        for(;;){
                bp = qbread(lb->q, Maxtu);
@@ -112,6 +112,7 @@ loopbackread(void *a)
                runlock(&ifc->rwlock);
                poperror();
        }
+       poperror();
 }
 
 struct medium loopbackmedium =
index f90f16a..a2dfa02 100644 (file)
@@ -120,7 +120,9 @@ netdevread(void *a)
        er->readp = current;    /* hide identity under a rock for unbind */
        if(waserror()){
                er->readp = NULL;
-               //      pexit("hangup", 1);
+               warn("netdevread returns unexpectedly");
+               poperror();
+               return;
        }
        for(;;){
                bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxtu, 0);
@@ -128,14 +130,16 @@ netdevread(void *a)
                        /*
                         * get here if mchan is a pipe and other side hangs up
                         * clean up this interface & get out
-ZZZ is this a good idea?
+ZZZ is this a good idea?  (watch your errors btw)
                         */
                        poperror();
                        er->readp = NULL;
                        argv[0] = "unbind";
                        if(!waserror())
                                ifc->conv->p->ctl(ifc->conv, argv, 1);
-                       //              pexit("hangup", 1);
+                       poperror();
+                       warn("netdevread returns unexpectedly");
+                       return;
                }
                if(!canrlock(&ifc->rwlock)){
                        freeb(bp);
@@ -153,6 +157,7 @@ ZZZ is this a good idea?
                runlock(&ifc->rwlock);
                poperror();
        }
+       poperror();
 }
 
 void
index 6126de9..d63b9e1 100644 (file)
@@ -86,7 +86,7 @@ netloginit(struct Fs *f)
 void
 netlogopen(struct Fs *f)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        spin_lock(&f->alog->lock);
        if(waserror()){
                spin_unlock(&f->alog->lock);
@@ -106,7 +106,7 @@ netlogopen(struct Fs *f)
 void
 netlogclose(struct Fs *f)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        spin_lock(&f->alog->lock);
        if(waserror()){
                spin_unlock(&f->alog->lock);
@@ -132,7 +132,7 @@ netlogready(void *a)
 long
 netlogread(struct Fs *f, void *a, uint32_t unused, long n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i, d;
        char *p, *rptr;
 
@@ -178,7 +178,7 @@ netlogread(struct Fs *f, void *a, uint32_t unused, long n)
 void
 netlogctl(struct Fs *f, char* s, int n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i, set = 0;
        Netlogflag *fp;
        struct cmdbuf *cb;
@@ -211,6 +211,7 @@ netlogctl(struct Fs *f, char* s, int n)
                else
                        f->alog->iponlyset = 1;
                kfree(cb);
+               poperror();
                return;
 
        default:
index 56e46db..274ccc2 100644 (file)
@@ -547,7 +547,7 @@ tcpclose(struct conv *c)
 void
 tcpkick(void *x)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct conv *s = x;
        Tcpctl *tcb;
 
@@ -597,7 +597,7 @@ tcprcvwin(struct conv *s)                           /* Call with tcb locked */
 void
 tcpacktimer(void *v)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        Tcpctl *tcb;
        struct conv *s;
 
@@ -660,7 +660,7 @@ timerstate(struct tcppriv *priv, Tcptimer *t, int newstate)
 void
 tcpackproc(void *a)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        Tcptimer *t, *tp, *timeo;
        struct Proto *tcp;
        struct tcppriv *priv;
@@ -694,8 +694,10 @@ tcpackproc(void *a)
                for(t = timeo; t != NULL; t = t->readynext) {
                        if(loop++ > 10000)
                                panic("tcpackproc2");
-                       if(t->state == TcptimerDONE && t->func != NULL && !waserror()){
-                               (*t->func)(t->arg);
+                       if(t->state == TcptimerDONE && t->func != NULL) {
+                               /* discard error style */
+                               if (!waserror())
+                                       (*t->func)(t->arg);
                                poperror();
                        }
                }
@@ -1340,9 +1342,12 @@ tcphangup(struct conv *s)
        struct block *hbp;
 
        tcb = (Tcpctl*)s->ptcl;
-       if(waserror())
+       if(waserror()) {
+               poperror();
                return commonerror();
+       }
        if(s->raddr != 0) {
+               /* discard error style, poperror regardless */
                if(!waserror()){
                        seg.flags = RST | ACK;
                        seg.ack = tcb->rcv.nxt;
@@ -1366,8 +1371,8 @@ tcphangup(struct conv *s)
                        default:
                                panic("tcphangup: version %d", s->ipversion);
                        }
-                       poperror();
                }
+               poperror();
        }
        localclose(s, NULL);
        poperror();
@@ -1936,7 +1941,7 @@ done:
 void
 tcpiput(struct Proto *tcp, struct Ipifc*unused, struct block *bp)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        Tcp seg;
        Tcp4hdr *h4;
        Tcp6hdr *h6;
@@ -2706,7 +2711,7 @@ tcpsetkacounter(Tcpctl *tcb)
 void
 tcpkeepalive(void *v)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        Tcpctl *tcb;
        struct conv *s;
 
@@ -2792,7 +2797,7 @@ tcprxmit(struct conv *s)
 void
 tcptimeout(void *arg)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct conv *s;
        Tcpctl *tcb;
        int maxback;
index b30b18a..a0da9d0 100644 (file)
@@ -368,7 +368,7 @@ struct mhead *newmhead(struct chan *from)
 int
 cmount(struct chan *new, struct chan *old, int flag, char *spec)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct pgrp *pg;
        int order, flg;
        struct mhead *m, **l, *mh;
@@ -618,7 +618,7 @@ domount(struct chan **cp, struct mhead **mp)
 struct chan*
 undomount(struct chan *c, struct cname *name)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *nc;
        struct pgrp *pg;
        struct mount *t;
@@ -827,7 +827,7 @@ walk(struct chan **cp, char **names, int nnames, int nomount, int *nerror)
 struct chan*
 createdir(struct chan *c, struct mhead *m)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *nc;
        struct mount *f;
 
@@ -846,6 +846,7 @@ createdir(struct chan *c, struct mhead *m)
                }
        }
        error(Enocreate);
+       poperror();
        return 0;
 }
 
@@ -968,13 +969,13 @@ memrchr(void *va, int c, long n)
 struct chan*
 namec(char *aname, int amode, int omode, uint32_t perm)
 {
-       ERRSTACK(4);
+       ERRSTACK(2);
        int n, prefix, len, t, nomount, npath;
        struct chan *c, *cnew;
        struct cname *cname;
        Elemlist e;
        struct mhead *m;
-       char *createerr, tmperrbuf[ERRMAX];
+       char tmperrbuf[ERRMAX];
        char *name;
        // Rune r;
 
@@ -1083,12 +1084,12 @@ namec(char *aname, int amode, int omode, uint32_t perm)
                        printd("namec %s walk error npath=%d\n", aname, npath);
                        error("walk failed");
                }
-#warning "fix this mess with errstr and walking"
-#if 0
-               strncpy(tmperrbuf,  current->errstr, sizeof(tmperrbuf));
-#endif
        NameError:
+               error("some kinda name error");
+               /* brho: skipping the namec custom error string business, since it hides
+                * the underlying failure.  implement this if you want the old stuff. */
 #if 0
+               strncpy(tmperrbuf,  current->errstr, sizeof(tmperrbuf));
                len = prefix+e.off[npath];
                if(len < ERRMAX/3 || (name=memrchr(aname, '/', len))==NULL || name==aname)
                        snprintf(get_cur_genbuf(), sizeof current->genbuf, "%.*s", len, aname);
@@ -1096,7 +1097,6 @@ namec(char *aname, int amode, int omode, uint32_t perm)
                        snprintf(get_cur_genbuf(), sizeof current->genbuf, "...%.*s", (int)(len-(name-aname)), name);
                snprintf(current->errstr, ERRMAX, "%#q %s", get_cur_genbuf(), tmperrbuf);
 #endif
-               error("some kinda name error");
        }
 
        if(e.mustbedir && !(c->qid.type&QTDIR)){
@@ -1247,6 +1247,7 @@ if(c->umh != NULL){
                 */
                m = NULL;
                cnew = NULL;    /* is this assignment necessary? */
+               /* discard error */
                if(!waserror()){        /* try create */
                        if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
                                cnew = createdir(cnew, m);
@@ -1285,20 +1286,16 @@ if(c->umh != NULL){
                if(m)
                        putmhead(m);
                if(omode & OEXCL)
-                       nexterror();
-               /* save error */
-#warning "more mess with errstr"
-#if 0
-               createerr = current->errstr;
-               current->errstr = tmperrbuf;
-#endif
+                       nexterror();    /* safe since we're in a waserror() */
+               poperror();             /* matching the if(!waserror) */
+
+               /* save error, so walk doesn't clobber our existing errstr */         
+               strncpy(tmperrbuf, current_errstr(), MAX_ERRSTR_LEN);                 
                /* note: we depend that walk does not error */
-               if(walk(&c, e.elems+e.ARRAY_SIZEs-1, 1, nomount, NULL) < 0){
-                       error(createerr);       /* report true error */
+               if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, nomount, NULL) < 0) {
+                       error(tmperrbuf);   /* report the error we had originally */      
                }
-#if 0
-               set_errstr(createerr);
-#endif
+               strncpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN); 
                omode |= OTRUNC;
                goto Open;
 
index b0919fb..8d991c6 100644 (file)
@@ -44,7 +44,7 @@ ncmdfield(char *p, int n)
 struct cmdbuf*
 parsecmd(char *p, int n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct cmdbuf *volatile cb;
        int nf;
        char *sp;
index bef61df..9014fae 100644 (file)
@@ -947,7 +947,7 @@ bl2mem(uint8_t *p, struct block *b, int n)
 struct block*
 mem2bl(uint8_t *p, int len)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int n;
        struct block *b, *first, **l;
 
@@ -1020,7 +1020,7 @@ qwakeup_iunlock(struct queue *q)
 struct block*
 qbread(struct queue *q, int len)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct block *b, *nb;
        int n;
 
@@ -1076,7 +1076,7 @@ qbread(struct queue *q, int len)
 long
 qread(struct queue *q, void *vp, int len)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct block *b, *first, **l;
        int m, n;
 
@@ -1172,7 +1172,7 @@ uint32_t noblockcnt;
 long
 qbwrite(struct queue *q, struct block *b)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int n, dowakeup;
 
        n = BLEN(b);
@@ -1271,7 +1271,7 @@ qbwrite(struct queue *q, struct block *b)
 int
 qwrite(struct queue *q, void *vp, int len)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int n, sofar;
        struct block *b;
        uint8_t *p = vp;
index 3fedadb..2bbee4b 100644 (file)
@@ -116,7 +116,7 @@ randominit(void)
 uint32_t
 randomread(void *xp, uint32_t n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i, sofar;
        uint8_t *e, *p;
 
index bd09065..5479c84 100644 (file)
@@ -117,13 +117,15 @@ fdtochan(struct fgrp *f, int fd, int mode, int chkmnt, int iref)
 long
 kchanio(void *vc, void *buf, int n, int mode)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int r;
        struct chan *c;
 
        c = vc;
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        if(mode == OREAD)
                r = devtab[c->type]->read(c, buf, n, c->offset);
@@ -182,12 +184,14 @@ fdclose(struct fgrp *f, int fd)
 int
 syschdir(char *path)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *c;
        struct pgrp *pg;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = namec(path, Atodir, 0, 0);
        pg = current->pgrp;
@@ -200,9 +204,11 @@ syschdir(char *path)
 int
 fgrpclose(struct fgrp *f, int fd)
 {
-       ERRSTACK(2);
-       if(waserror())
+       ERRSTACK(1);
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        /*
         * Take no reference on the chan because we don't really need the
@@ -228,8 +234,10 @@ syscreate(char *path, int mode, uint32_t perm)
        int fd;
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        openmode(mode&~OEXCL);  /* error check only; OEXCL okay here */
        c = namec(path, Acreate, mode, perm);
@@ -254,8 +262,10 @@ sysdup(int old, int new)
        struct chan *c, *oc;
        struct fgrp *f = current->fgrp;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = fdtochan(current->fgrp, old, -1, 0, 1);
        if(c->qid.type & QTAUTH)
@@ -301,8 +311,10 @@ sysfstat(int fd, uint8_t *buf, int n)
        ERRSTACK(2);
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = fdtochan(current->fgrp, fd, -1, 0, 1);
        if(waserror()) {
@@ -321,12 +333,14 @@ sysfstat(int fd, uint8_t *buf, int n)
 char*
 sysfd2path(int fd)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *c;
        char *s;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return NULL;
+       }
        c = fdtochan(current->fgrp, fd, -1, 0, 1);
        s = NULL;
        if(c->name != NULL){
@@ -348,8 +362,10 @@ sysfauth(int fd, char *aname)
        ERRSTACK(2);
        struct chan *c, *ac;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        validname(aname, 0);
        c = fdtochan(current->fgrp, fd, ORDWR, 0, 1);
@@ -386,8 +402,10 @@ sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen)
        int m;
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        /* check there's a NUL in the version string */
        if(arglen==0 || memchr(vers, 0, arglen)==0)
@@ -411,7 +429,7 @@ sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen)
 int
 syspipe(int fd[2])
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct dev *d;
        struct fgrp *f;
        struct chan *c[2];
@@ -439,6 +457,7 @@ syspipe(int fd[2])
                        put_fd(&current->open_files, fd[1]);
                        f->fd[fd[1]]=0;
                }
+               poperror();
                return -1;
        }
        c[1] = cclone(c[0]);
@@ -464,8 +483,10 @@ sysfwstat(int fd, uint8_t *buf, int n)
        ERRSTACK(2);
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        validstat(buf, n);
        c = fdtochan(current->fgrp, fd, -1, 1, 1);
@@ -484,7 +505,7 @@ sysfwstat(int fd, uint8_t *buf, int n)
 long
 bindmount(struct chan *c, char *old, int flag, char *spec)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int ret;
        struct chan *c1;
 
@@ -510,8 +531,10 @@ sysbind(char *new, char *old, int flags)
        long r;
        struct chan *c0;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c0 = namec(new, Abind, 0, 0);
        if(waserror()) {
@@ -529,7 +552,7 @@ sysbind(char *new, char *old, int flags)
 int
 sysmount(int fd, int afd, char *old, int flags, char *spec)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        long r;
        volatile struct { struct chan *c; } c0;
        volatile struct { struct chan *c; } bc;
@@ -543,6 +566,7 @@ sysmount(int fd, int afd, char *old, int flags, char *spec)
                cclose(ac.c);
                cclose(bc.c);
                cclose(c0.c);
+               poperror();
                return -1;
        }
        bc.c = fdtochan(current->fgrp, fd, ORDWR, 0, 1);
@@ -566,7 +590,7 @@ sysmount(int fd, int afd, char *old, int flags, char *spec)
 int
 sysunmount(char *old, char *new)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        volatile struct { struct chan *c; } cmount;
        volatile struct { struct chan *c; } cmounted;
 
@@ -575,6 +599,7 @@ sysunmount(char *old, char *new)
        if(waserror()) {
                cclose(cmount.c);
                cclose(cmounted.c);
+               poperror();
                return -1;
        }
 
@@ -603,8 +628,10 @@ sysopen(char *path, int mode)
        int fd;
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        openmode(mode);                         /* error check only */
        c = namec(path, Aopen, mode, 0);
@@ -624,7 +651,7 @@ sysopen(char *path, int mode)
 long
 unionread(struct chan *c, void *va, long n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i;
        long nr;
        struct mhead *m;
@@ -641,17 +668,19 @@ unionread(struct chan *c, void *va, long n)
        nr = 0;
        while(mount != NULL) {
                /* Error causes component of union to be skipped */
-               if(mount->to && !waserror()) {
-                       if(c->umc == NULL){
-                               c->umc = cclone(mount->to);
-                               c->umc = devtab[c->umc->type]->open(c->umc, OREAD);
-                       }
+               if(mount->to) {
+                       if (!waserror()) { /* discard style */
+                               if(c->umc == NULL){
+                                       c->umc = cclone(mount->to);
+                                       c->umc = devtab[c->umc->type]->open(c->umc, OREAD);
+                               }
        
-                       nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset);
-                       if(nr < 0)
-                               nr = 0; /* dev.c can return -1 */
-                       c->umc->offset += nr;
-                       poperror();
+                               nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset);
+                               if(nr < 0)
+                                       nr = 0; /* dev.c can return -1 */
+                               c->umc->offset += nr;
+                       }
+                       poperror(); /* pop regardless */
                }
                if(nr > 0)
                        break;
@@ -689,8 +718,10 @@ rread(int fd, void *va, long n, int64_t *offp)
        struct chan *c;
        int64_t off;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = fdtochan(current->fgrp, fd, OREAD, 1, 1);
        if(waserror()) {
@@ -753,8 +784,10 @@ sysremove(char *path)
        ERRSTACK(2);
        struct chan *c;
 
-       if(waserror())
-               return -1;
+       if (waserror()) {
+               poperror();
+               return -1; 
+       }
 
        c = namec(path, Aremove, 0, 0);
        if(waserror()) {
@@ -782,8 +815,10 @@ sysseek(int fd, int64_t off, int whence)
        struct dir *dir;
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = fdtochan(current->fgrp, fd, -1, 1, 1);
        if(waserror()) {
@@ -879,8 +914,10 @@ sysstat(char *path, uint8_t *buf, int n)
        ERRSTACK(2);
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        c = namec(path, Aaccess, 0, 0);
        if(waserror()){
@@ -898,13 +935,15 @@ sysstat(char *path, uint8_t *buf, int n)
 static long
 rwrite(int fd, void *va, long n, int64_t *offp)
 {
-       ERRSTACK(2);
+       ERRSTACK(3);
        struct chan *c;
        int64_t off;
        long m;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
        c = fdtochan(current->fgrp, fd, OWRITE, 1, 1);
        if(waserror()) {
                cclose(c);
@@ -968,8 +1007,10 @@ syswstat(char *path, uint8_t *buf, int n)
        ERRSTACK(2);
        struct chan *c;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
 
        validstat(buf, n);
        c = namec(path, Aaccess, 0, 0);
@@ -994,7 +1035,7 @@ enum
 struct dir*
 chandirstat(struct chan *c)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct dir *d;
        uint8_t *buf;
        int n, nd, i;
@@ -1005,6 +1046,7 @@ chandirstat(struct chan *c)
                buf = ( uint8_t *)&d[1];
                if(waserror()){
                        kfree(d);
+                       poperror();
                        return NULL;
                }
                n = devtab[c->type]->stat(c, buf, nd);
@@ -1032,8 +1074,10 @@ sysdirstat(char *name)
        struct chan *c;
        struct dir *d;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return NULL;
+       }
 
        c = namec(name, Aaccess, 0, 0);
        if(waserror()){
@@ -1055,8 +1099,10 @@ sysdirfstat(int fd)
        struct chan *c;
        struct dir *d;
 
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return NULL;
+       }
 
        c = fdtochan(current->fgrp, fd, -1, 0, 1);
        if(waserror()) {
@@ -1156,8 +1202,10 @@ sysdirread(int fd, struct dir **d)
        long ts;
 
        *d = NULL;
-       if(waserror())
+       if (waserror()) {
+               poperror();
                return -1;
+       }
        buf = kzmalloc(DIRREADLIM, 0);
        if(buf == NULL)
                error(Enomem);
@@ -1177,13 +1225,14 @@ sysdirread(int fd, struct dir **d)
 int
 sysiounit(int fd)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        struct chan *c;
        int n;
 
        c = fdtochan(current->fgrp, fd, -1, 0, 1);
        if(waserror()){
                cclose(c);
+               poperror();
                return 0;       /* n.b. */
        }
        n = c->iounit;