tTweaks to various bits. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 49588d5d9089589ccda28c41aae90c29d6f72787
 (DIR) parent 7f11104a5737adf261d10bc1a7b85e740f2eb491
 (HTM) Author: rsc <devnull@localhost>
       Date:   Wed, 17 Dec 2003 04:34:52 +0000
       
       Tweaks to various bits.
       
       Until I hear otherwise, Refs aren't used enough to
       merit their own assembly.  They are now implemented with locks.
       
       Diffstat:
         M src/cmd/9pserve.c                   |      67 ++++++++++++++++++++-----------
         M src/cmd/acme/fsys.c                 |       7 +++++--
         M src/cmd/acme/mkfile                 |       2 +-
         M src/cmd/acme/xfid.c                 |       1 +
         M src/cmd/mkfile                      |       2 +-
         M src/lib9/notify.c                   |      57 ++++++++++++++++++-------------
         M src/libfs/ns.c                      |       1 +
         M src/libplumb/mesg.c                 |      73 ++++++++++++++++++++++---------
         M src/libthread/asm-FreeBSD-386.s     |      34 ++++++++++++++++----------------
         M src/libthread/exec-unix.c           |       1 +
         M src/libthread/ref.c                 |      11 +++++++++--
       
       11 files changed, 166 insertions(+), 90 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c
       t@@ -352,8 +352,8 @@ connthread(void *arg)
                                m->afid->ref++;
                                break;
                        case Topenfd:
       -                        if(m->tx.mode != OREAD && (m->tx.mode&~OTRUNC) != OWRITE){
       -                                err(m, "openfd mode must be OREAD or OWRITE");
       +                        if(m->tx.mode&~(OTRUNC|3)){
       +                                err(m, "bad openfd mode");
                                        continue;
                                }
                                m->isopenfd = 1;
       t@@ -489,13 +489,17 @@ openfdthread(void *v)
                                m->ref++;
                                sendomsg(m);
                                recvp(c->internal);
       -                        if(m->rx.type == Rerror)
       +                        if(m->rx.type == Rerror){
       +                        //        fprint(2, "read error: %s\n", m->rx.ename);
                                        break;
       +                        }
                                if(m->rx.count == 0)
                                        break;
                                tot += m->rx.count;
       -                        if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count)
       +                        if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
       +                                fprint(2, "pipe write error: %r\n");
                                        break;
       +                        }
                                msgput(m);
                                msgput(m);
                        }
       t@@ -503,6 +507,8 @@ openfdthread(void *v)
                        for(;;){
                                if(verbose) fprint(2, "twrite...");
                                if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){
       +                                if(n < 0)
       +                                        fprint(2, "pipe read error: %r\n");
                                        m = nil;
                                        break;
                                }
       t@@ -520,8 +526,10 @@ openfdthread(void *v)
                                m->ref++;
                                sendomsg(m);
                                recvp(c->internal);
       -                        if(m->rx.type == Rerror)
       -                                break;
       +                        if(m->rx.type == Rerror){
       +                        //        fprint(2, "write error: %s\n", m->rx.ename);
       +                                continue;
       +                        }
                                tot = n;
                                msgput(m);
                                msgput(m);
       t@@ -534,18 +542,20 @@ openfdthread(void *v)
                        msgput(m);
                        msgput(m);
                }
       -        m = msgnew();
       -        m->internal = 1;
       -        m->c = c;
       -        m->tx.type = Tclunk;
       -        m->tx.fid = fid->fid;
       -        m->fid = fid;
       -        fid->ref++;
       -        m->ref++;
       -        sendomsg(m);
       -        recvp(c->internal);
       -        msgput(m);
       -        msgput(m);
       +        if(fid->ref == 1){
       +                m = msgnew();
       +                m->internal = 1;
       +                m->c = c;
       +                m->tx.type = Tclunk;
       +                m->tx.fid = fid->fid;
       +                m->fid = fid;
       +                fid->ref++;
       +                m->ref++;
       +                sendomsg(m);
       +                recvp(c->internal);
       +                msgput(m);
       +                msgput(m);
       +        }
                fidput(fid);
                c->fdfid = nil;
                chanfree(c->internal);
       t@@ -578,13 +588,24 @@ xopenfd(Msg *m)
                nc->fdmode = m->tx.mode;
                nc->fd = p[0];
        
       -        /* clunk fid from other connection */
       -        if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
       -                fidput(m->fid);
       -
                /* a thread to tend the pipe */
                threadcreate(openfdthread, nc, STACK);
        
       +        /* if mode is ORDWR, that openfdthread will write; start a reader */
       +        if((m->tx.mode&3) == ORDWR){
       +                nc = emalloc(sizeof(Conn));
       +                nc->internal = chancreate(sizeof(void*), 0);
       +                nc->fdfid = m->fid;
       +                m->fid->ref++;
       +                nc->fdmode = OREAD;
       +                nc->fd = dup(p[0], -1);
       +                threadcreate(openfdthread, nc, STACK);
       +        }
       +
       +        /* steal fid from other connection */
       +        if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
       +                fidput(m->fid);
       +
                /* rewrite as Ropenfd */
                m->rx.type = Ropenfd;
                n = GBIT32(m->rpkt);
       t@@ -1265,7 +1286,7 @@ iowrite(Ioproc *io, int fd, void *v, long n)
                u = v;
                for(tot=0; tot<n; tot+=m){
                        m = _iowrite(io, fd, u+tot, n-tot);
       -                if(m <= 0){
       +                if(m < 0){
                                if(tot)
                                        break;
                                return m;
 (DIR) diff --git a/src/cmd/acme/fsys.c b/src/cmd/acme/fsys.c
       t@@ -306,6 +306,7 @@ fsysattach(Xfid *x, Fid *f)
                Fcall t;
                int id;
                Mntdir *m;
       +        char buf[128];
        
                if(strcmp(x->fcall.uname, user) != 0)
                        return respond(x, &t, Eperm);
       t@@ -327,8 +328,10 @@ fsysattach(Xfid *x, Fid *f)
                                m->ref++;
                                break;
                        }
       -        if(m == nil)
       -                sendp(cerr, estrdup("unknown id in attach"));
       +        if(m == nil){
       +                snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
       +                sendp(cerr, estrdup(buf));
       +        }
                qunlock(&mnt.lk);
                return respond(x, &t, nil);
        }
 (DIR) diff --git a/src/cmd/acme/mkfile b/src/cmd/acme/mkfile
       t@@ -36,6 +36,6 @@ UPDATE=\
        
        <$PLAN9/src/mkone
        
       -LDFLAGS=$LDFLAGS -lfs -lmux -lplumb -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
       +LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
        
        edit.$O ecmd.$O elog.$O:        edit.h
 (DIR) diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c
       t@@ -194,6 +194,7 @@ xfidclose(Xfid *x)
        
                w = x->f->w;
                x->f->busy = FALSE;
       +        x->f->w = nil;
                if(x->f->open == FALSE){
                        if(w != nil)
                                winclose(w);
 (DIR) diff --git a/src/cmd/mkfile b/src/cmd/mkfile
       t@@ -6,7 +6,7 @@ LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -lbio -l9 -lfmt -lutf
        
        <$PLAN9/src/mkmany
        
       -BUGGERED='CVS|oplumb|plumb2|mk|vac|9term|venti|htmlfmt'
       +BUGGERED='CVS|faces|factotum|oplumb|plumb2|mk|vac|9term|upas|venti|htmlfmt'
        DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"`
        
        <$PLAN9/src/mkdirs
 (DIR) diff --git a/src/lib9/notify.c b/src/lib9/notify.c
       t@@ -7,33 +7,37 @@
        
        extern char *_p9sigstr(int, char*);
        
       -static int sigs[] = {
       -        SIGHUP,
       -        SIGINT,
       -        SIGQUIT,
       -        SIGILL,
       -        SIGTRAP,
       +static struct {
       +        int sig;
       +        int restart;
       +} sigs[] = {
       +        SIGHUP, 0,
       +        SIGINT, 0,
       +        SIGQUIT, 0,
       +        SIGILL, 0,
       +        SIGTRAP, 0,
        /*        SIGABRT,        */
        #ifdef SIGEMT
       -        SIGEMT,
       +        SIGEMT, 0,
        #endif
       -        SIGFPE,
       -        SIGBUS,
       +        SIGFPE, 0,
       +        SIGBUS, 0,
        /*        SIGSEGV,        */
       -        SIGSYS,
       -        SIGPIPE,
       -        SIGALRM,
       -        SIGTERM,
       -        SIGTSTP,
       -        SIGTTIN,
       -        SIGTTOU,
       -        SIGXCPU,
       -        SIGXFSZ,
       -        SIGVTALRM,
       -        SIGUSR1,
       -        SIGUSR2,
       +        SIGCHLD, 1,
       +        SIGSYS, 0,
       +        SIGPIPE, 0,
       +        SIGALRM, 0,
       +        SIGTERM, 0,
       +        SIGTSTP, 1,
       +        SIGTTIN, 1,
       +        SIGTTOU, 1,
       +        SIGXCPU, 0,
       +        SIGXFSZ, 0,
       +        SIGVTALRM, 0,
       +        SIGUSR1, 0,
       +        SIGUSR2, 0,
        #ifdef SIGINFO
       -        SIGINFO,
       +        SIGINFO, 0,
        #endif
        };
        
       t@@ -72,8 +76,13 @@ notify(void (*f)(void*, char*))
                        notifyf = f;
                        sa.sa_handler = notifysigf;
                }
       -        for(i=0; i<nelem(sigs); i++)
       -                sigaction(sigs[i], &sa, 0);
       +        for(i=0; i<nelem(sigs); i++){
       +                if(sigs[i].restart)
       +                        sa.sa_flags |= SA_RESTART;
       +                else
       +                        sa.sa_flags &= ~SA_RESTART;
       +                sigaction(sigs[i].sig, &sa, 0);
       +        }
                return 0;
        }
        
 (DIR) diff --git a/src/libfs/ns.c b/src/libfs/ns.c
       t@@ -25,6 +25,7 @@ nsmount(char *name, char *aname)
                        werrstr("dial %s: %r", addr);
                        return nil;
                }
       +        fcntl(fd, F_SETFL, FD_CLOEXEC);
        
                fs = fsmount(fd, aname);
                if(fs == nil){
 (DIR) diff --git a/src/libplumb/mesg.c b/src/libplumb/mesg.c
       t@@ -7,21 +7,68 @@
        static char attrbuf[4096];
        
        char *home;
       -
       +static Fsys *fsplumb;
       +static int pfd = -1;
       +static Fid *pfid;
        int
        plumbopen(char *name, int omode)
        {
       -        Fsys *fs;
                int fd;
        
       -        fs = nsmount("plumb", "");
       -        if(fs == nil)
       +        if(fsplumb == nil)
       +                fsplumb = nsmount("plumb", "");
       +        if(fsplumb == nil)
                        return -1;
       -        fd = fsopenfd(fs, name, omode);
       -        fsunmount(fs);
       +        /*
       +         * It's important that when we send something,
       +         * we find out whether it was a valid plumb write.
       +         * (If it isn't, the client might fall back to some
       +         * other mechanism or indicate to the user what happened.)
       +         * We can't use a pipe for this, so we have to use the
       +         * fid interface.  But we need to return a fd. 
       +         * Return a fd for /dev/null so that we return a unique
       +         * file descriptor.  In plumbsend we'll look for pfd
       +         * and use the recorded fid instead.
       +         */
       +        if((omode&3) == OWRITE){
       +                if(pfd != -1){
       +                        werrstr("already have plumb send open");
       +                        return -1;
       +                }
       +                pfd = open("/dev/null", OWRITE);
       +                if(pfd < 0)
       +                        return -1;
       +                pfid = fsopen(fsplumb, name, omode);
       +                if(pfid == nil){
       +                        close(pfd);
       +                        pfd = -1;
       +                        return -1;
       +                }
       +                return pfd;
       +        }
       +
       +        fd = fsopenfd(fsplumb, name, omode);
                return fd;
        }
        
       +int
       +plumbsend(int fd, Plumbmsg *m)
       +{
       +        char *buf;
       +        int n;
       +
       +        if(fd != pfd){
       +                werrstr("fd is not the plumber");
       +                return -1;
       +        }
       +        buf = plumbpack(m, &n);
       +        if(buf == nil)
       +                return -1;
       +        n = fswrite(pfid, buf, n);
       +        free(buf);
       +        return n;
       +}
       +
        static int
        Strlen(char *s)
        {
       t@@ -144,20 +191,6 @@ plumbpack(Plumbmsg *m, int *np)
                return buf;
        }
        
       -int
       -plumbsend(int fd, Plumbmsg *m)
       -{
       -        char *buf;
       -        int n;
       -
       -        buf = plumbpack(m, &n);
       -        if(buf == nil)
       -                return -1;
       -        n = write(fd, buf, n);
       -        free(buf);
       -        return n;
       -}
       -
        static int
        plumbline(char **linep, char *buf, int i, int n, int *bad)
        {
 (DIR) diff --git a/src/libthread/asm-FreeBSD-386.s b/src/libthread/asm-FreeBSD-386.s
       t@@ -30,20 +30,20 @@ _gotolabel:
                ret
        
        
       -.globl        _xinc
       -_xinc:
       -        movl 4(%esp), %eax
       -        lock incl 0(%eax)
       -        ret
       -
       -.globl        _xdec
       -_xdec:
       -        movl 4(%esp), %eax
       -        lock decl 0(%eax)
       -        jz iszero
       -        movl $1, %eax
       -        ret
       -iszero:
       -        movl $0, %eax
       -        ret
       -
       +# .globl        _xinc
       +# _xinc:
       +#         movl 4(%esp), %eax
       +#         lock incl 0(%eax)
       +#         ret
       +# 
       +# .globl        _xdec
       +# _xdec:
       +#         movl 4(%esp), %eax
       +#         lock decl 0(%eax)
       +#         jz iszero
       +#         movl $1, %eax
       +#         ret
       +# iszero:
       +#         movl $0, %eax
       +#         ret
       +# 
 (DIR) diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c
       t@@ -122,6 +122,7 @@ efork(void *ve)
                for(i=3; i<40; i++)
                        if(i != e->fd[1])
                                close(i);
       +        rfork(RFNOTEG);
                execvp(e->prog, e->args);
                _threaddebug(DBGEXEC, "_schedexec failed: %r");
                rerrstr(buf, sizeof buf);
 (DIR) diff --git a/src/libthread/ref.c b/src/libthread/ref.c
       t@@ -3,11 +3,18 @@
        void
        incref(Ref *r)
        {
       -        _xinc(&r->ref);
       +        lock(&r->lk);
       +        r->ref++;
       +        unlock(&r->lk);
        }
        
        long
        decref(Ref *r)
        {
       -        return _xdec(&r->ref);
       +        long n;
       +
       +        lock(&r->lk);
       +        n = --r->ref;
       +        unlock(&r->lk);
       +        return n;
        }