tsync with plan 9 - 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 c8f538425f4e92e1e438b9bd25cb08e250a93d5b
 (DIR) parent 79049567a0fac8707ea3f2927403445bdb2394fa
 (HTM) Author: rsc <devnull@localhost>
       Date:   Mon, 26 Mar 2007 12:02:41 +0000
       
       sync with plan 9
       
       Diffstat:
         M src/cmd/rc/code.c                   |     223 +++++++++++++++++++------------
         M src/cmd/rc/exec.c                   |     989 ++++++++++++++++---------------
         M src/cmd/rc/exec.h                   |      10 +++++++---
         M src/cmd/rc/fns.h                    |      10 ++++++----
         M src/cmd/rc/getflags.c               |     171 ++++++++++++++++++-------------
         M src/cmd/rc/glob.c                   |     165 +++++++++++++++++++------------
         M src/cmd/rc/havefork.c               |      10 ----------
         A src/cmd/rc/havep9p.c                |     246 +++++++++++++++++++++++++++++++
         M src/cmd/rc/here.c                   |      97 ++++++++++++++++++-------------
         M src/cmd/rc/io.c                     |     231 +++++++++++++++++++++----------
         M src/cmd/rc/io.h                     |       6 +++---
         M src/cmd/rc/lex.c                    |     278 ++++++++++++++++++-------------
         M src/cmd/rc/mkfile                   |       1 +
         M src/cmd/rc/pcmd.c                   |     107 +++++++++++++++++++++----------
         M src/cmd/rc/pfnc.c                   |      16 ++++++++++------
         M src/cmd/rc/plan9ish.c               |       4 +++-
         M src/cmd/rc/rc.h                     |       1 +
         M src/cmd/rc/simple.c                 |     329 ++++++++++++++++++-------------
         M src/cmd/rc/subr.c                   |      47 +++++++++++++++++++++----------
         M src/cmd/rc/syn.y                    |       3 ---
         M src/cmd/rc/trap.c                   |      25 ++++++++++++++-----------
         M src/cmd/rc/tree.c                   |     132 +++++++++++++++++++------------
         M src/cmd/rc/var.c                    |      98 ++++++++++++++++++++++---------
       
       23 files changed, 1967 insertions(+), 1232 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/rc/code.c b/src/cmd/rc/code.c
       t@@ -7,9 +7,9 @@
        #define        c1        t->child[1]
        #define        c2        t->child[2]
        int codep, ncode;
       -#define        emitf(x) ((void)(codep!=ncode || morecode()), codebuf[codep].f=(x), codep++)
       -#define        emiti(x) ((void)(codep!=ncode || morecode()), codebuf[codep].i=(x), codep++)
       -#define        emits(x) ((void)(codep!=ncode || morecode()), codebuf[codep].s=(x), codep++)
       +#define        emitf(x) ((void)(codep!=ncode || morecode()), codebuf[codep].f = (x), codep++)
       +#define        emiti(x) ((void)(codep!=ncode || morecode()), codebuf[codep].i = (x), codep++)
       +#define        emits(x) ((void)(codep!=ncode || morecode()), codebuf[codep].s = (x), codep++)
        void stuffdot(int);
        char *fnstr(tree*);
        void outcode(tree*, int);
       t@@ -17,22 +17,32 @@ void codeswitch(tree*, int);
        int iscase(tree*);
        code *codecopy(code*);
        void codefree(code*);
       -int morecode(void){
       +
       +int
       +morecode(void)
       +{
                ncode+=100;
       -        codebuf=(code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
       -        if(codebuf==0) panic("Can't realloc %d bytes in morecode!",
       +        codebuf = (code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
       +        if(codebuf==0)
       +                panic("Can't realloc %d bytes in morecode!",
                                        ncode*sizeof codebuf[0]);
                return 0;
        }
       -void stuffdot(int a){
       -        if(a<0 || codep<=a) panic("Bad address %d in stuffdot", a);
       -        codebuf[a].i=codep;
       +
       +void
       +stuffdot(int a)
       +{
       +        if(a<0 || codep<=a)
       +                panic("Bad address %d in stuffdot", a);
       +        codebuf[a].i = codep;
        }
       -int compile(tree *t)
       +
       +int
       +compile(tree *t)
        {
       -        ncode=100;
       -        codebuf=(code *)emalloc(ncode*sizeof codebuf[0]);
       -        codep=0;
       +        ncode = 100;
       +        codebuf = (code *)emalloc(ncode*sizeof codebuf[0]);
       +        codep = 0;
                emiti(0);                        /* reference count */
                outcode(t, flag['e']?1:0);
                if(nerror){
       t@@ -44,31 +54,39 @@ int compile(tree *t)
                emitf(0);
                return 1;
        }
       -void cleanhere(char *f)
       +
       +void
       +cleanhere(char *f)
        {
                emitf(Xdelhere);
                emits(strdup(f));
        }
       -char *fnstr(tree *t)
       +
       +char*
       +fnstr(tree *t)
        {
       -        io *f=openstr();
       +        io *f = openstr();
                char *v;
                extern char nl;
       -        char svnl=nl;
       +        char svnl = nl;
                nl=';';
                pfmt(f, "%t", t);
       -        nl=svnl;
       -        v=f->strp;
       -        f->strp=0;
       +        nl = svnl;
       +        v = f->strp;
       +        f->strp = 0;
                closeio(f);
                return v;
        }
       -void outcode(tree *t, int eflag)
       +
       +void
       +outcode(tree *t, int eflag)
        {
                int p, q;
                tree *tt;
       -        if(t==0) return;
       -        if(t->type!=NOT && t->type!=';') runq->iflast=0;
       +        if(t==0)
       +                return;
       +        if(t->type!=NOT && t->type!=';')
       +                runq->iflast = 0;
                switch(t->type){
                default:
                        pfmt(err, "bad type %d in outcode\n", t->type);
       t@@ -92,10 +110,13 @@ void outcode(tree *t, int eflag)
                        break;
                case '&':
                        emitf(Xasync);
       -                p=emiti(0);
       -                outcode(c0, eflag);
       -                emitf(Xexit);
       -                stuffdot(p);
       +                if(havefork){
       +                        p = emiti(0);
       +                        outcode(c0, eflag);
       +                        emitf(Xexit);
       +                        stuffdot(p);
       +                } else
       +                        emits(fnstr(c0));
                        break;
                case ';':
                        outcode(c0, eflag);
       t@@ -110,15 +131,18 @@ void outcode(tree *t, int eflag)
                        break;
                case '`':
                        emitf(Xbackq);
       -                p=emiti(0);
       -                outcode(c0, 0);
       -                emitf(Xexit);
       -                stuffdot(p);
       +                if(havefork){
       +                        p = emiti(0);
       +                        outcode(c0, 0);
       +                        emitf(Xexit);
       +                        stuffdot(p);
       +                } else
       +                        emits(fnstr(c0));
                        break;
                case ANDAND:
                        outcode(c0, 0);
                        emitf(Xtrue);
       -                p=emiti(0);
       +                p = emiti(0);
                        outcode(c1, eflag);
                        stuffdot(p);
                        break;
       t@@ -144,7 +168,7 @@ void outcode(tree *t, int eflag)
                        outcode(c0, eflag);
                        if(c1){
                                emitf(Xfn);
       -                        p=emiti(0);
       +                        p = emiti(0);
                                emits(fnstr(c1));
                                outcode(c1, eflag);
                                emitf(Xunlocal);        /* get rid of $* */
       t@@ -157,22 +181,23 @@ void outcode(tree *t, int eflag)
                case IF:
                        outcode(c0, 0);
                        emitf(Xif);
       -                p=emiti(0);
       +                p = emiti(0);
                        outcode(c1, eflag);
                        emitf(Xwastrue);
                        stuffdot(p);
                        break;
                case NOT:
       -                if(!runq->iflast) yyerror("`if not' does not follow `if(...)'");
       +                if(!runq->iflast)
       +                        yyerror("`if not' does not follow `if(...)'");
                        emitf(Xifnot);
       -                p=emiti(0);
       +                p = emiti(0);
                        outcode(c0, eflag);
                        stuffdot(p);
                        break;
                case OROR:
                        outcode(c0, 0);
                        emitf(Xfalse);
       -                p=emiti(0);
       +                p = emiti(0);
                        outcode(c1, eflag);
                        stuffdot(p);
                        break;
       t@@ -183,15 +208,20 @@ void outcode(tree *t, int eflag)
                        emitf(Xmark);
                        outcode(c0, eflag);
                        emitf(Xsimple);
       -                if(eflag) emitf(Xeflag);
       +                if(eflag)
       +                        emitf(Xeflag);
                        break;
                case SUBSHELL:
                        emitf(Xsubshell);
       -                p=emiti(0);
       -                outcode(c0, eflag);
       -                emitf(Xexit);
       -                stuffdot(p);
       -                if(eflag) emitf(Xeflag);
       +                if(havefork){
       +                        p = emiti(0);
       +                        outcode(c0, eflag);
       +                        emitf(Xexit);
       +                        stuffdot(p);
       +                } else
       +                        emits(fnstr(c0));
       +                if(eflag)
       +                        emitf(Xeflag);
                        break;
                case SWITCH:
                        codeswitch(t, eflag);
       t@@ -202,14 +232,16 @@ void outcode(tree *t, int eflag)
                        emitf(Xmark);
                        outcode(c0, eflag);
                        emitf(Xmatch);
       -                if(eflag) emitf(Xeflag);
       +                if(eflag)
       +                        emitf(Xeflag);
                        break;
                case WHILE:
       -                q=codep;
       +                q = codep;
                        outcode(c0, 0);
       -                if(q==codep) emitf(Xsettrue);        /* empty condition == while(true) */
       +                if(q==codep)
       +                        emitf(Xsettrue);        /* empty condition == while(true) */
                        emitf(Xtrue);
       -                p=emiti(0);
       +                p = emiti(0);
                        outcode(c1, eflag);
                        emitf(Xjump);
                        emiti(q);
       t@@ -235,8 +267,8 @@ void outcode(tree *t, int eflag)
                        emitf(Xmark);
                        outcode(c0, eflag);
                        emitf(Xlocal);
       -                p=emitf(Xfor);
       -                q=emiti(0);
       +                p = emitf(Xfor);
       +                q = emiti(0);
                        outcode(c2, eflag);
                        emitf(Xjump);
                        emiti(p);
       t@@ -263,10 +295,14 @@ void outcode(tree *t, int eflag)
                case PIPEFD:
                        emitf(Xpipefd);
                        emiti(t->rtype);
       -                p=emiti(0);
       -                outcode(c0, eflag);
       -                emitf(Xexit);
       -                stuffdot(p);
       +                if(havefork){
       +                        p = emiti(0);
       +                        outcode(c0, eflag);
       +                        emitf(Xexit);
       +                        stuffdot(p);
       +                } else {
       +                        emits(fnstr(c0));
       +                }
                        break;
                case REDIR:
                        emitf(Xmark);
       t@@ -283,28 +319,31 @@ void outcode(tree *t, int eflag)
                        case HERE:
                                emitf(Xread);
                                break;
       +                case RDWR:
       +                        emitf(Xrdwr);
       +                        break;
                        }
                        emiti(t->fd0);
                        outcode(c1, eflag);
                        emitf(Xpopredir);
                        break;
                case '=':
       -                tt=t;
       -                for(;t && t->type=='=';t=c2);
       +                tt = t;
       +                for(;t && t->type=='=';t = c2);
                        if(t){
       -                        for(t=tt;t->type=='=';t=c2){
       +                        for(t = tt;t->type=='=';t = c2){
                                        emitf(Xmark);
                                        outcode(c1, eflag);
                                        emitf(Xmark);
                                        outcode(c0, eflag);
                                        emitf(Xlocal);
                                }
       -                        t=tt;
       +                        t = tt;
                                outcode(c2, eflag);
       -                        for(;t->type=='=';t=c2) emitf(Xunlocal);
       +                        for(;t->type=='=';t = c2) emitf(Xunlocal);
                        }
                        else{
       -                        for(t=tt;t;t=c2){
       +                        for(t = tt;t;t = c2){
                                        emitf(Xmark);
                                        outcode(c1, eflag);
                                        emitf(Xmark);
       t@@ -312,17 +351,22 @@ void outcode(tree *t, int eflag)
                                        emitf(Xassign);
                                }
                        }
       -                t=tt;        /* so tests below will work */
       +                t = tt;        /* so tests below will work */
                        break;
                case PIPE:
                        emitf(Xpipe);
                        emiti(t->fd0);
                        emiti(t->fd1);
       -                p=emiti(0);
       -                q=emiti(0);
       -                outcode(c0, eflag);
       -                emitf(Xexit);
       -                stuffdot(p);
       +                if(havefork){
       +                        p = emiti(0);
       +                        q = emiti(0);
       +                        outcode(c0, eflag);
       +                        emitf(Xexit);
       +                        stuffdot(p);
       +                } else {
       +                        emits(fnstr(c0));
       +                        q = emiti(0);
       +                }
                        outcode(c1, eflag);
                        emitf(Xreturn);
                        stuffdot(q);
       t@@ -330,8 +374,8 @@ void outcode(tree *t, int eflag)
                        break;
                }
                if(t->type!=NOT && t->type!=';')
       -                runq->iflast=t->type==IF;
       -        else if(c0) runq->iflast=c0->type==IF;
       +                runq->iflast = t->type==IF;
       +        else if(c0) runq->iflast = c0->type==IF;
        }
        /*
         * switch code looks like this:
       t@@ -353,7 +397,9 @@ void outcode(tree *t, int eflag)
         * leave:
         *        Xpopm
         */
       -void codeswitch(tree *t, int eflag)
       +
       +void
       +codeswitch(tree *t, int eflag)
        {
                int leave;                /* patch jump address to leave switch */
                int out;                /* jump here to leave switch */
       t@@ -368,23 +414,23 @@ void codeswitch(tree *t, int eflag)
                emitf(Xmark);
                outcode(c0, eflag);
                emitf(Xjump);
       -        nextcase=emiti(0);
       -        out=emitf(Xjump);
       -        leave=emiti(0);
       +        nextcase = emiti(0);
       +        out = emitf(Xjump);
       +        leave = emiti(0);
                stuffdot(nextcase);
       -        t=c1->child[0];
       +        t = c1->child[0];
                while(t->type==';'){
       -                tt=c1;
       +                tt = c1;
                        emitf(Xmark);
       -                for(t=c0->child[0];t->type==ARGLIST;t=c0) outcode(c1, eflag);
       +                for(t = c0->child[0];t->type==ARGLIST;t = c0) outcode(c1, eflag);
                        emitf(Xcase);
       -                nextcase=emiti(0);
       -                t=tt;
       +                nextcase = emiti(0);
       +                t = tt;
                        for(;;){
                                if(t->type==';'){
                                        if(iscase(c0)) break;
                                        outcode(c0, eflag);
       -                                t=c1;
       +                                t = c1;
                                }
                                else{
                                        if(!iscase(t)) outcode(t, eflag);
       t@@ -398,23 +444,32 @@ void codeswitch(tree *t, int eflag)
                stuffdot(leave);
                emitf(Xpopm);
        }
       -int iscase(tree *t)
       +
       +int
       +iscase(tree *t)
        {
       -        if(t->type!=SIMPLE) return 0;
       -        do t=c0; while(t->type==ARGLIST);
       +        if(t->type!=SIMPLE)
       +                return 0;
       +        do t = c0; while(t->type==ARGLIST);
                return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0;
        }
       -code *codecopy(code *cp)
       +
       +code*
       +codecopy(code *cp)
        {
                cp[0].i++;
                return cp;
        }
       -void codefree(code *cp)
       +
       +void
       +codefree(code *cp)
        {
                code *p;
       -        if(--cp[0].i!=0) return;
       -        for(p=cp+1;p->f;p++){
       +        if(--cp[0].i!=0)
       +                return;
       +        for(p = cp+1;p->f;p++){
                        if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite
       +                || p->f==Xrdwr
                        || p->f==Xasync || p->f==Xbackq || p->f==Xcase || p->f==Xfalse
                        || p->f==Xfor || p->f==Xjump
                        || p->f==Xsubshell || p->f==Xtrue) p++;
 (DIR) diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
       t@@ -1,9 +1,3 @@
       -#include <u.h>
       -#include <signal.h>
       -#if defined(PLAN9PORT) && defined(__sun__)
       -#        define BSD_COMP        /* sigh.  for TIOCNOTTY */
       -#endif
       -#include <sys/ioctl.h>
        #include "rc.h"
        #include "getflags.h"
        #include "exec.h"
       t@@ -13,91 +7,118 @@
         * Start executing the given code at the given pc with the given redirection
         */
        char *argv0="rc";
       -void start(code *c, int pc, var *local)
       -{
       -        struct thread *p=new(struct thread);
       -        p->code=codecopy(c);
       -        p->pc=pc;
       -        p->argv=0;
       -        p->redir=p->startredir=runq?runq->redir:0;
       -        p->local=local;
       -        p->cmdfile=0;
       -        p->cmdfd=0;
       -        p->eof=0;
       -        p->iflag=0;
       -        p->lineno=1;
       -        p->pid=-1;
       -        p->ret=runq;
       -        runq=p;
       -}
       -word *newword(char *wd, word *next)
       -{
       -        word *p=new(word);
       -        p->word=strdup(wd);
       -        p->next=next;
       +
       +void
       +start(code *c, int pc, var *local)
       +{
       +        struct thread *p = new(struct thread);
       +
       +        p->code = codecopy(c);
       +        p->pc = pc;
       +        p->argv = 0;
       +        p->redir = p->startredir = runq?runq->redir:0;
       +        p->local = local;
       +        p->cmdfile = 0;
       +        p->cmdfd = 0;
       +        p->eof = 0;
       +        p->iflag = 0;
       +        p->lineno = 1;
       +        p->ret = runq;
       +        runq = p;
       +}
       +
       +word*
       +newword(char *wd, word *next)
       +{
       +        word *p = new(word);
       +        p->word = strdup(wd);
       +        p->next = next;
                return p;
        }
       -void pushword(char *wd)
       +
       +void
       +pushword(char *wd)
        {
       -        if(runq->argv==0) panic("pushword but no argv!", 0);
       -        runq->argv->words=newword(wd, runq->argv->words);
       +        if(runq->argv==0)
       +                panic("pushword but no argv!", 0);
       +        runq->argv->words = newword(wd, runq->argv->words);
        }
       -void popword(void){
       +
       +void
       +popword(void)
       +{
                word *p;
       -        if(runq->argv==0) panic("popword but no argv!", 0);
       -        p=runq->argv->words;
       -        if(p==0) panic("popword but no word!", 0);
       -        runq->argv->words=p->next;
       +        if(runq->argv==0)
       +                panic("popword but no argv!", 0);
       +        p = runq->argv->words;
       +        if(p==0)
       +                panic("popword but no word!", 0);
       +        runq->argv->words = p->next;
                efree(p->word);
                efree((char *)p);
        }
       -void freelist(word *w)
       +
       +void
       +freelist(word *w)
        {
                word *nw;
                while(w){
       -                nw=w->next;
       +                nw = w->next;
                        efree(w->word);
                        efree((char *)w);
       -                w=nw;
       +                w = nw;
                }
        }
       -void pushlist(void){
       -        list *p=new(list);
       -        p->next=runq->argv;
       -        p->words=0;
       -        runq->argv=p;
       +
       +void
       +pushlist(void)
       +{
       +        list *p = new(list);
       +        p->next = runq->argv;
       +        p->words = 0;
       +        runq->argv = p;
        }
       -void poplist(void){
       -        list *p=runq->argv;
       -        if(p==0) panic("poplist but no argv", 0);
       +
       +void
       +poplist(void)
       +{
       +        list *p = runq->argv;
       +        if(p==0)
       +                panic("poplist but no argv", 0);
                freelist(p->words);
       -        runq->argv=p->next;
       +        runq->argv = p->next;
                efree((char *)p);
        }
       -int count(word *w)
       +
       +int
       +count(word *w)
        {
                int n;
       -        for(n=0;w;n++) w=w->next;
       +        for(n = 0;w;n++) w = w->next;
                return n;
        }
       -void pushredir(int type, int from, int to){
       -        redir * rp=new(redir);
       -        rp->type=type;
       -        rp->from=from;
       -        rp->to=to;
       -        rp->next=runq->redir;
       -        runq->redir=rp;
       -}
       -var *newvar(char *name, var *next)
       -{
       -        var *v=new(var);
       -        v->name=name;
       -        v->val=0;
       -        v->fn=0;
       -        v->changed=0;
       -        v->fnchanged=0;
       -        v->next=next;
       -        v->changefn = 0;
       +
       +void
       +pushredir(int type, int from, int to)
       +{
       +        redir * rp = new(redir);
       +        rp->type = type;
       +        rp->from = from;
       +        rp->to = to;
       +        rp->next = runq->redir;
       +        runq->redir = rp;
       +}
       +
       +var*
       +newvar(char *name, var *next)
       +{
       +        var *v = new(var);
       +        v->name = name;
       +        v->val = 0;
       +        v->fn = 0;
       +        v->changed = 0;
       +        v->fnchanged = 0;
       +        v->next = next;
                return v;
        }
        /*
       t@@ -117,50 +138,55 @@ main(int argc, char *argv[])
                /* needed for rcmain later */
                putenv("PLAN9", unsharp("#9"));
        
       -        argc=getflags(argc, argv, "srdiIlxepvVc:1m:1[command]", 1);
       -        if(argc==-1) usage("[file [arg ...]]");
       -        if(argv[0][0]=='-') flag['l']=flagset;
       -        if(flag['I']) flag['i'] = 0;
       +        argc = getflags(argc, argv, "SsrdiIlxepvVc:1m:1[command]", 1);
       +        if(argc==-1)
       +                usage("[file [arg ...]]");
       +        if(argv[0][0]=='-')
       +                flag['l'] = flagset;
       +        if(flag['I'])
       +                flag['i'] = 0;
                else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;
       -        rcmain=flag['m']?flag['m'][0]:Rcmain(); 
       -        err=openfd(2);
       +        rcmain = flag['m'] ? flag['m'][0] : Rcmain();
       +        err = openfd(2);
                kinit();
                Trapinit();
                Vinit();
       -        itoa(num, mypid=getpid());
       +        inttoascii(num, mypid = getpid());
                pathinit();
                setvar("pid", newword(num, (word *)0));
                setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
                                        :(word *)0);
                setvar("rcname", newword(argv[0], (word *)0));
       -        i=0;
       -        bootstrap[i++].i=1;
       -        bootstrap[i++].f=Xmark;
       -        bootstrap[i++].f=Xword;
       +        i = 0;
       +        bootstrap[i++].i = 1;
       +        bootstrap[i++].f = Xmark;
       +        bootstrap[i++].f = Xword;
                bootstrap[i++].s="*";
       -        bootstrap[i++].f=Xassign;
       -        bootstrap[i++].f=Xmark;
       -        bootstrap[i++].f=Xmark;
       -        bootstrap[i++].f=Xword;
       +        bootstrap[i++].f = Xassign;
       +        bootstrap[i++].f = Xmark;
       +        bootstrap[i++].f = Xmark;
       +        bootstrap[i++].f = Xword;
                bootstrap[i++].s="*";
       -        bootstrap[i++].f=Xdol;
       -        bootstrap[i++].f=Xword;
       -        bootstrap[i++].s=rcmain;
       -        bootstrap[i++].f=Xword;
       +        bootstrap[i++].f = Xdol;
       +        bootstrap[i++].f = Xword;
       +        bootstrap[i++].s = rcmain;
       +        bootstrap[i++].f = Xword;
                bootstrap[i++].s=".";
       -        bootstrap[i++].f=Xsimple;
       -        bootstrap[i++].f=Xexit;
       -        bootstrap[i].i=0;
       +        bootstrap[i++].f = Xsimple;
       +        bootstrap[i++].f = Xexit;
       +        bootstrap[i].i = 0;
                start(bootstrap, 1, (var *)0);
                /* prime bootstrap argv */
                pushlist();
                argv0 = strdup(argv[0]);
       -        for(i=argc-1;i!=0;--i) pushword(argv[i]);
       +        for(i = argc-1;i!=0;--i) pushword(argv[i]);
                for(;;){
       -                if(flag['r']) pfnc(err, runq);
       +                if(flag['r'])
       +                        pfnc(err, runq);
                        runq->pc++;
                        (*runq->code[runq->pc-1].f)();
       -                if(ntrap) dotrap();
       +                if(ntrap)
       +                        dotrap();
                }
        }
        /*
       t@@ -197,6 +223,7 @@ main(int argc, char *argv[])
         * Xpipefd[type]{... Xreturn}                connect {} to pipe (input or output,
         *                                         depending on type), push /dev/fd/??
         * Xpopm(value)                                pop value from stack
       + * Xrdwr(file)[fd]                        open file for reading and writing
         * Xread(file)[fd]                        open file to read
         * Xsettraps(names){... Xreturn}                define trap functions
         * Xshowtraps                                print trap list
       t@@ -208,16 +235,24 @@ main(int argc, char *argv[])
         * Xword[string]                        push string
         * Xwrite(file)[fd]                        open file to write
         */
       -void Xappend(void){
       +
       +void
       +Xappend(void)
       +{
                char *file;
                int f;
                switch(count(runq->argv->words)){
       -        default: Xerror1(">> requires singleton"); return;
       -        case 0: Xerror1(">> requires file"); return;
       -        case 1: break;
       +        default:
       +                Xerror1(">> requires singleton");
       +                return;
       +        case 0:
       +                Xerror1(">> requires file");
       +                return;
       +        case 1:
       +                break;
                }
       -        file=runq->argv->words->word;
       -        if((f=open(file, 1))<0 && (f=Creat(file))<0){
       +        file = runq->argv->words->word;
       +        if((f = open(file, 1))<0 && (f = Creat(file))<0){
                        pfmt(err, "%s: ", file);
                        Xerror("can't open");
                        return;
       t@@ -227,126 +262,114 @@ void Xappend(void){
                runq->pc++;
                poplist();
        }
       -void Xasync(void){
       -        int null=open("/dev/null", 0);
       -        int tty;
       -        int pid;
       -        char npid[10];
       -        if(null<0){
       -                Xerror("Can't open /dev/null\n");
       -                return;
       -        }
       -        switch(pid=rfork(RFFDG|RFPROC|RFNOTEG)){
       -        case -1:
       -                close(null);
       -                Xerror("try again");
       -                break;
       -        case 0:
       -                /*
       -                 * I don't know what the right thing to do here is,
       -                 * so this is all experimentally determined.
       -                 * If we just dup /dev/null onto 0, then running
       -                 * ssh foo & will reopen /dev/tty, try to read a password,
       -                 * get a signal, and repeat, in a tight loop, forever.
       -                 * Arguably this is a bug in ssh (it behaves the same
       -                 * way under bash as under rc) but I'm fixing it here 
       -                 * anyway.  If we dissociate the process from the tty,
       -                 * then it won't be able to open /dev/tty ever again.
       -                 * The SIG_IGN on SIGTTOU makes writing the tty
       -                 * (via fd 1 or 2, for example) succeed even though 
       -                 * our pgrp is not the terminal's controlling pgrp.
       -                 */
       -                if((tty=open("/dev/tty", OREAD)) >= 0){
       -                        /*
       -                         * Should make reads of tty fail, writes succeed.
       -                         */
       -                        signal(SIGTTIN, SIG_IGN);
       -                        signal(SIGTTOU, SIG_IGN);
       -                        ioctl(tty, TIOCNOTTY);
       -                        close(tty);
       -                }
       -                if(isatty(0))
       -                        pushredir(ROPEN, null, 0);
       -                else
       -                        close(null);
       -                start(runq->code, runq->pc+1, runq->local);
       -                runq->ret=0;
       -                break;
       -        default:
       -                close(null);
       -                runq->pc=runq->code[runq->pc].i;
       -                itoa(npid, pid);
       -                setvar("apid", newword(npid, (word *)0));
       -                break;
       -        }
       -}
       -void Xsettrue(void){
       +
       +void
       +Xsettrue(void)
       +{
                setstatus("");
        }
       -void Xbang(void){
       +
       +void
       +Xbang(void)
       +{
                setstatus(truestatus()?"false":"");
        }
       -void Xclose(void){
       +
       +void
       +Xclose(void)
       +{
                pushredir(RCLOSE, runq->code[runq->pc].i, 0);
                runq->pc++;
        }
       -void Xdup(void){
       +
       +void
       +Xdup(void)
       +{
                pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);
                runq->pc+=2;
        }
       -void Xeflag(void){
       +
       +void
       +Xeflag(void)
       +{
                if(eflagok && !truestatus()) Xexit();
        }
       -void Xexit(void){
       +
       +void
       +Xexit(void)
       +{
                struct var *trapreq;
                struct word *starval;
       -        static int beenhere=0;
       +        static int beenhere = 0;
                if(getpid()==mypid && !beenhere){
       -                trapreq=vlook("sigexit");
       +                trapreq = vlook("sigexit");
                        if(trapreq->fn){
       -                        beenhere=1;
       +                        beenhere = 1;
                                --runq->pc;
       -                        starval=vlook("*")->val;
       +                        starval = vlook("*")->val;
                                start(trapreq->fn, trapreq->pc, (struct var *)0);
       -                        runq->local=newvar(strdup("*"), runq->local);
       -                        runq->local->val=copywords(starval, (struct word *)0);
       -                        runq->local->changed=1;
       -                        runq->redir=runq->startredir=0;
       +                        runq->local = newvar(strdup("*"), runq->local);
       +                        runq->local->val = copywords(starval, (struct word *)0);
       +                        runq->local->changed = 1;
       +                        runq->redir = runq->startredir = 0;
                                return;
                        }
                }
                Exit(getstatus());
        }
       -void Xfalse(void){
       -        if(truestatus()) runq->pc=runq->code[runq->pc].i;
       +
       +void
       +Xfalse(void)
       +{
       +        if(truestatus()) runq->pc = runq->code[runq->pc].i;
                else runq->pc++;
        }
        int ifnot;                /* dynamic if not flag */
       -void Xifnot(void){
       +
       +void
       +Xifnot(void)
       +{
                if(ifnot)
                        runq->pc++;
                else
       -                runq->pc=runq->code[runq->pc].i;
       +                runq->pc = runq->code[runq->pc].i;
        }
       -void Xjump(void){
       -        runq->pc=runq->code[runq->pc].i;
       +
       +void
       +Xjump(void)
       +{
       +        runq->pc = runq->code[runq->pc].i;
        }
       -void Xmark(void){
       +
       +void
       +Xmark(void)
       +{
                pushlist();
        }
       -void Xpopm(void){
       +
       +void
       +Xpopm(void)
       +{
                poplist();
        }
       -void Xread(void){
       +
       +void
       +Xread(void)
       +{
                char *file;
                int f;
                switch(count(runq->argv->words)){
       -        default: Xerror1("< requires singleton\n"); return;
       -        case 0: Xerror1("< requires file\n"); return;
       -        case 1: break;
       +        default:
       +                Xerror1("< requires singleton\n");
       +                return;
       +        case 0:
       +                Xerror1("< requires file\n");
       +                return;
       +        case 1:
       +                break;
                }
       -        file=runq->argv->words->word;
       -        if((f=open(file, 0))<0){
       +        file = runq->argv->words->word;
       +        if((f = open(file, 0))<0){
                        pfmt(err, "%s: ", file);
                        Xerror("can't open");
                        return;
       t@@ -355,51 +378,110 @@ void Xread(void){
                runq->pc++;
                poplist();
        }
       -void turfredir(void){
       +
       +void
       +Xrdwr(void)
       +{
       +        char *file;
       +        int f;
       +
       +        switch(count(runq->argv->words)){
       +        default:
       +                Xerror1("<> requires singleton\n");
       +                return;
       +        case 0:
       +                Xerror1("<> requires file\n");
       +                return;
       +        case 1:
       +                break;
       +        }
       +        file = runq->argv->words->word;
       +        if((f = open(file, ORDWR))<0){
       +                pfmt(err, "%s: ", file);
       +                Xerror("can't open");
       +                return;
       +        }
       +        pushredir(ROPEN, f, runq->code[runq->pc].i);
       +        runq->pc++;
       +        poplist();
       +}
       +
       +void
       +turfredir(void)
       +{
                while(runq->redir!=runq->startredir)
                        Xpopredir();
        }
       -void Xpopredir(void){
       -        struct redir *rp=runq->redir;
       -        if(rp==0) panic("turfredir null!", 0);
       -        runq->redir=rp->next;
       -        if(rp->type==ROPEN) close(rp->from);
       +
       +void
       +Xpopredir(void)
       +{
       +        struct redir *rp = runq->redir;
       +        if(rp==0)
       +                panic("turfredir null!", 0);
       +        runq->redir = rp->next;
       +        if(rp->type==ROPEN)
       +                close(rp->from);
                efree((char *)rp);
        }
       -void Xreturn(void){
       -        struct thread *p=runq;
       +
       +void
       +Xreturn(void)
       +{
       +        struct thread *p = runq;
                turfredir();
                while(p->argv) poplist();
                codefree(p->code);
       -        runq=p->ret;
       +        runq = p->ret;
                efree((char *)p);
       -        if(runq==0) Exit(getstatus());
       +        if(runq==0)
       +                Exit(getstatus());
        }
       -void Xtrue(void){
       +
       +void
       +Xtrue(void)
       +{
                if(truestatus()) runq->pc++;
       -        else runq->pc=runq->code[runq->pc].i;
       +        else runq->pc = runq->code[runq->pc].i;
        }
       -void Xif(void){
       -        ifnot=1;
       +
       +void
       +Xif(void)
       +{
       +        ifnot = 1;
                if(truestatus()) runq->pc++;
       -        else runq->pc=runq->code[runq->pc].i;
       +        else runq->pc = runq->code[runq->pc].i;
        }
       -void Xwastrue(void){
       -        ifnot=0;
       +
       +void
       +Xwastrue(void)
       +{
       +        ifnot = 0;
        }
       -void Xword(void){
       +
       +void
       +Xword(void)
       +{
                pushword(runq->code[runq->pc++].s);
        }
       -void Xwrite(void){
       +
       +void
       +Xwrite(void)
       +{
                char *file;
                int f;
                switch(count(runq->argv->words)){
       -        default: Xerror1("> requires singleton\n"); return;
       -        case 0: Xerror1("> requires file\n"); return;
       -        case 1: break;
       +        default:
       +                Xerror1("> requires singleton\n");
       +                return;
       +        case 0:
       +                Xerror1("> requires file\n");
       +                return;
       +        case 1:
       +                break;
                }
       -        file=runq->argv->words->word;
       -        if((f=Creat(file))<0){
       +        file = runq->argv->words->word;
       +        if((f = Creat(file))<0){
                        pfmt(err, "%s: ", file);
                        Xerror("can't open");
                        return;
       t@@ -408,31 +490,35 @@ void Xwrite(void){
                runq->pc++;
                poplist();
        }
       -char *_list2str(word *words, int c){
       +
       +char*
       +list2str(word *words)
       +{
                char *value, *s, *t;
       -        int len=0;
       +        int len = 0;
                word *ap;
       -        for(ap=words;ap;ap=ap->next)
       +        for(ap = words;ap;ap = ap->next)
                        len+=1+strlen(ap->word);
       -        value=emalloc(len+1);
       -        s=value;
       -        for(ap=words;ap;ap=ap->next){
       -                for(t=ap->word;*t;) *s++=*t++;
       -                *s++=c;
       -        }
       -        if(s==value) *s='\0';
       +        value = emalloc(len+1);
       +        s = value;
       +        for(ap = words;ap;ap = ap->next){
       +                for(t = ap->word;*t;) *s++=*t++;
       +                *s++=' ';
       +        }
       +        if(s==value)
       +                *s='\0';
                else s[-1]='\0';
                return value;
        }
       -char *list2str(word *words){
       -        return _list2str(words, ' ');
       -}
       -void Xmatch(void){
       +
       +void
       +Xmatch(void)
       +{
                word *p;
                char *subject;
       -        subject=list2str(runq->argv->words);
       +        subject = list2str(runq->argv->words);
                setstatus("no match");
       -        for(p=runq->argv->next->words;p;p=p->next)
       +        for(p = runq->argv->next->words;p;p = p->next)
                        if(match(subject, p->word, '\0')){
                                setstatus("");
                                break;
       t@@ -441,14 +527,17 @@ void Xmatch(void){
                poplist();
                poplist();
        }
       -void Xcase(void){
       +
       +void
       +Xcase(void)
       +{
                word *p;
                char *s;
       -        int ok=0;
       -        s=list2str(runq->argv->next->words);
       -        for(p=runq->argv->words;p;p=p->next){
       +        int ok = 0;
       +        s = list2str(runq->argv->next->words);
       +        for(p = runq->argv->words;p;p = p->next){
                        if(match(s, p->word, '\0')){
       -                        ok=1;
       +                        ok = 1;
                                break;
                        }
                }
       t@@ -456,28 +545,33 @@ void Xcase(void){
                if(ok)
                        runq->pc++;
                else
       -                runq->pc=runq->code[runq->pc].i;
       +                runq->pc = runq->code[runq->pc].i;
                poplist();
        }
       -word *conclist(word *lp, word *rp, word *tail)
       +
       +word*
       +conclist(word *lp, word *rp, word *tail)
        {
                char *buf;
                word *v;
                if(lp->next || rp->next)
       -                tail=conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
       +                tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
                                tail);
       -        buf=emalloc(strlen(lp->word)+strlen(rp->word)+1);
       +        buf = emalloc(strlen(lp->word)+strlen(rp->word)+1);
                strcpy(buf, lp->word);
                strcat(buf, rp->word);
       -        v=newword(buf, tail);
       +        v = newword(buf, tail);
                efree(buf);
                return v;
        }
       -void Xconc(void){
       -        word *lp=runq->argv->words;
       -        word *rp=runq->argv->next->words;
       -        word *vp=runq->argv->next->next->words;
       -        int lc=count(lp), rc=count(rp);
       +
       +void
       +Xconc(void)
       +{
       +        word *lp = runq->argv->words;
       +        word *rp = runq->argv->next->words;
       +        word *vp = runq->argv->next->next->words;
       +        int lc = count(lp), rc = count(rp);
                if(lc!=0 || rc!=0){
                        if(lc==0 || rc==0){
                                Xerror1("null list in concatenation");
       t@@ -487,42 +581,48 @@ void Xconc(void){
                                Xerror1("mismatched list lengths in concatenation");
                                return;
                        }
       -                vp=conclist(lp, rp, vp);
       +                vp = conclist(lp, rp, vp);
                }
                poplist();
                poplist();
       -        runq->argv->words=vp;
       +        runq->argv->words = vp;
        }
       -void Xassign(void){
       +
       +void
       +Xassign(void)
       +{
                var *v;
                if(count(runq->argv->words)!=1){
                        Xerror1("variable name not singleton!");
                        return;
                }
                deglob(runq->argv->words->word);
       -        v=vlook(runq->argv->words->word);
       +        v = vlook(runq->argv->words->word);
                poplist();
                globlist();
                freewords(v->val);
       -        v->val=runq->argv->words;
       -        v->changed=1;
       -        if(v->changefn)
       -                v->changefn(v);
       -        runq->argv->words=0;
       +        v->val = runq->argv->words;
       +        v->changed = 1;
       +        runq->argv->words = 0;
                poplist();
        }
        /*
         * copy arglist a, adding the copy to the front of tail
         */
       -word *copywords(word *a, word *tail)
       +
       +word*
       +copywords(word *a, word *tail)
        {
       -        word *v=0, **end;
       -        for(end=&v;a;a=a->next,end=&(*end)->next)
       -                *end=newword(a->word, 0);
       -        *end=tail;
       +        word *v = 0, **end;
       +        for(end=&v;a;a = a->next,end=&(*end)->next)
       +                *end = newword(a->word, 0);
       +        *end = tail;
                return v;
        }
       -void Xdol(void){
       +
       +void
       +Xdol(void)
       +{
                word *a, *star;
                char *s, *t;
                int n;
       t@@ -530,24 +630,27 @@ void Xdol(void){
                        Xerror1("variable name not singleton!");
                        return;
                }
       -        s=runq->argv->words->word;
       +        s = runq->argv->words->word;
                deglob(s);
       -        n=0;
       -        for(t=s;'0'<=*t && *t<='9';t++) n=n*10+*t-'0';
       -        a=runq->argv->next->words;
       +        n = 0;
       +        for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
       +        a = runq->argv->next->words;
                if(n==0 || *t)
       -                a=copywords(vlook(s)->val, a);
       +                a = copywords(vlook(s)->val, a);
                else{
       -                star=vlook("*")->val;
       +                star = vlook("*")->val;
                        if(star && 1<=n && n<=count(star)){
       -                        while(--n) star=star->next;
       -                        a=newword(star->word, a);
       +                        while(--n) star = star->next;
       +                        a = newword(star->word, a);
                        }
                }
                poplist();
       -        runq->argv->words=a;
       +        runq->argv->words = a;
        }
       -void Xqdol(void){
       +
       +void
       +Xqdol(void)
       +{
                word *a, *p;
                char *s;
                int n;
       t@@ -555,20 +658,20 @@ void Xqdol(void){
                        Xerror1("variable name not singleton!");
                        return;
                }
       -        s=runq->argv->words->word;
       +        s = runq->argv->words->word;
                deglob(s);
       -        a=vlook(s)->val;
       +        a = vlook(s)->val;
                poplist();
       -        n=count(a);
       +        n = count(a);
                if(n==0){
                        pushword("");
                        return;
                }
       -        for(p=a;p;p=p->next) n+=strlen(p->word);
       -        s=emalloc(n);
       +        for(p = a;p;p = p->next) n+=strlen(p->word);
       +        s = emalloc(n);
                if(a){
                        strcpy(s, a->word);
       -                for(p=a->next;p;p=p->next){
       +                for(p = a->next;p;p = p->next){
                                strcat(s, " ");
                                strcat(s, p->word);
                        }
       t@@ -578,37 +681,47 @@ void Xqdol(void){
                pushword(s);
                efree(s);
        }
       -word *subwords(word *val, int len, word *sub, word *a)
       +
       +word*
       +subwords(word *val, int len, word *sub, word *a)
        {
                int n;
                char *s;
       -        if(!sub) return a;
       -        a=subwords(val, len, sub->next, a);
       -        s=sub->word;
       +        if(!sub)
       +                return a;
       +        a = subwords(val, len, sub->next, a);
       +        s = sub->word;
                deglob(s);
       -        n=0;
       -        while('0'<=*s && *s<='9') n=n*10+ *s++ -'0';
       -        if(n<1 || len<n) return a;
       -        for(;n!=1;--n) val=val->next;
       +        n = 0;
       +        while('0'<=*s && *s<='9') n = n*10+ *s++ -'0';
       +        if(n<1 || len<n)
       +                return a;
       +        for(;n!=1;--n) val = val->next;
                return newword(val->word, a);
        }
       -void Xsub(void){
       +
       +void
       +Xsub(void)
       +{
                word *a, *v;
                char *s;
                if(count(runq->argv->next->words)!=1){
                        Xerror1("variable name not singleton!");
                        return;
                }
       -        s=runq->argv->next->words->word;
       +        s = runq->argv->next->words->word;
                deglob(s);
       -        a=runq->argv->next->next->words;
       -        v=vlook(s)->val;
       -        a=subwords(v, count(v), runq->argv->words, a);
       +        a = runq->argv->next->next->words;
       +        v = vlook(s)->val;
       +        a = subwords(v, count(v), runq->argv->words, a);
                poplist();
                poplist();
       -        runq->argv->words=a;
       +        runq->argv->words = a;
        }
       -void Xcount(void){
       +
       +void
       +Xcount(void)
       +{
                word *a;
                char *s, *t;
                int n;
       t@@ -617,112 +730,102 @@ void Xcount(void){
                        Xerror1("variable name not singleton!");
                        return;
                }
       -        s=runq->argv->words->word;
       +        s = runq->argv->words->word;
                deglob(s);
       -        n=0;
       -        for(t=s;'0'<=*t && *t<='9';t++) n=n*10+*t-'0';
       +        n = 0;
       +        for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
                if(n==0 || *t){
       -                a=vlook(s)->val;
       -                itoa(num, count(a));
       +                a = vlook(s)->val;
       +                inttoascii(num, count(a));
                }
                else{
       -                a=vlook("*")->val;
       -                itoa(num, a && 1<=n && n<=count(a)?1:0);
       +                a = vlook("*")->val;
       +                inttoascii(num, a && 1<=n && n<=count(a)?1:0);
                }
                poplist();
                pushword(num);
        }
       -void Xlocal(void){
       +
       +void
       +Xlocal(void)
       +{
                if(count(runq->argv->words)!=1){
                        Xerror1("variable name must be singleton\n");
                        return;
                }
                deglob(runq->argv->words->word);
       -        runq->local=newvar(strdup(runq->argv->words->word), runq->local);
       -        runq->local->val=copywords(runq->argv->next->words, (word *)0);
       -        runq->local->changed=1;
       +        runq->local = newvar(strdup(runq->argv->words->word), runq->local);
       +        runq->local->val = copywords(runq->argv->next->words, (word *)0);
       +        runq->local->changed = 1;
                poplist();
                poplist();
        }
       -void Xunlocal(void){
       -        var *v=runq->local, *hid;
       -        if(v==0) panic("Xunlocal: no locals!", 0);
       -        runq->local=v->next;
       -        hid=vlook(v->name);
       -        hid->changed=1;
       +
       +void
       +Xunlocal(void)
       +{
       +        var *v = runq->local, *hid;
       +        if(v==0)
       +                panic("Xunlocal: no locals!", 0);
       +        runq->local = v->next;
       +        hid = vlook(v->name);
       +        hid->changed = 1;
                efree(v->name);
                freewords(v->val);
                efree((char *)v);
        }
       -void freewords(word *w)
       +
       +void
       +freewords(word *w)
        {
                word *nw;
                while(w){
                        efree(w->word);
       -                nw=w->next;
       +                nw = w->next;
                        efree((char *)w);
       -                w=nw;
       +                w = nw;
                }
        }
       -void Xfn(void){
       +
       +void
       +Xfn(void)
       +{
                var *v;
                word *a;
                int end;
       -        end=runq->code[runq->pc].i;
       -        for(a=runq->argv->words;a;a=a->next){
       -                v=gvlook(a->word);
       -                if(v->fn) codefree(v->fn);
       -                v->fn=codecopy(runq->code);
       -                v->pc=runq->pc+2;
       -                v->fnchanged=1;
       -        }
       -        runq->pc=end;
       +        end = runq->code[runq->pc].i;
       +        for(a = runq->argv->words;a;a = a->next){
       +                v = gvlook(a->word);
       +                if(v->fn)
       +                        codefree(v->fn);
       +                v->fn = codecopy(runq->code);
       +                v->pc = runq->pc+2;
       +                v->fnchanged = 1;
       +        }
       +        runq->pc = end;
                poplist();
        }
       -void Xdelfn(void){
       +
       +void
       +Xdelfn(void)
       +{
                var *v;
                word *a;
       -        for(a=runq->argv->words;a;a=a->next){
       -                v=gvlook(a->word);
       -                if(v->fn) codefree(v->fn);
       -                v->fn=0;
       -                v->fnchanged=1;
       +        for(a = runq->argv->words;a;a = a->next){
       +                v = gvlook(a->word);
       +                if(v->fn)
       +                        codefree(v->fn);
       +                v->fn = 0;
       +                v->fnchanged = 1;
                }
                poplist();
        }
       -void Xpipe(void){
       -        struct thread *p=runq;
       -        int pc=p->pc, forkid;
       -        int lfd=p->code[pc++].i;
       -        int rfd=p->code[pc++].i;
       -        int pfd[2];
       -        if(pipe(pfd)<0){
       -                Xerror("can't get pipe");
       -                return;
       -        }
       -        switch(forkid=fork()){
       -        case -1:
       -                Xerror("try again");
       -                break;
       -        case 0:
       -                start(p->code, pc+2, runq->local);
       -                runq->ret=0;
       -                close(pfd[PRD]);
       -                pushredir(ROPEN, pfd[PWR], lfd);
       -                break;
       -        default:
       -                start(p->code, p->code[pc].i, runq->local);
       -                close(pfd[PWR]);
       -                pushredir(ROPEN, pfd[PRD], rfd);
       -                p->pc=p->code[pc+1].i;
       -                p->pid=forkid;
       -                break;
       -        }
       -}
       -char *concstatus(char *s, char *t)
       +
       +char*
       +concstatus(char *s, char *t)
        {
                static char v[NSTATUS+1];
       -        int n=strlen(s);
       +        int n = strlen(s);
                strncpy(v, s, NSTATUS);
                if(n<NSTATUS){
                        v[n]='|';
       t@@ -731,7 +834,10 @@ char *concstatus(char *s, char *t)
                v[NSTATUS]='\0';
                return v;
        }
       -void Xpipewait(void){
       +
       +void
       +Xpipewait(void)
       +{
                char status[NSTATUS+1];
                if(runq->pid==-1)
                        setstatus(concstatus(runq->status, getstatus()));
       t@@ -743,31 +849,35 @@ void Xpipewait(void){
                        setstatus(concstatus(getstatus(), status));
                }
        }
       -void Xrdcmds(void){
       -        struct thread *p=runq;
       +
       +void
       +Xrdcmds(void)
       +{
       +        struct thread *p = runq;
                word *prompt;
                flush(err);
       -        nerror=0;
       +        nerror = 0;
                if(flag['s'] && !truestatus())
                        pfmt(err, "status=%v\n", vlook("status")->val);
                if(runq->iflag){
       -                prompt=vlook("prompt")->val;
       +                prompt = vlook("prompt")->val;
                        if(prompt)
       -                        promptstr=prompt->word;
       +                        promptstr = prompt->word;
                        else
                                promptstr="% ";
                }
                Noerror();
                if(yyparse()){
                        if(!p->iflag || p->eof && !Eintr()){
       -                        if(p->cmdfile) efree(p->cmdfile);
       +                        if(p->cmdfile)
       +                                efree(p->cmdfile);
                                closeio(p->cmdfd);
                                Xreturn();        /* should this be omitted? */
                        }
                        else{
                                if(Eintr()){
                                        pchr(err, '\n');
       -                                p->eof=0;
       +                                p->eof = 0;
                                }
                                --p->pc;        /* go back for next command */
                        }
       t@@ -779,7 +889,9 @@ void Xrdcmds(void){
                }
                freenodes();
        }
       -void Xerror(char *s)
       +
       +void
       +Xerror(char *s)
        {
                if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
                        pfmt(err, "rc: %s: %r\n", s);
       t@@ -789,7 +901,9 @@ void Xerror(char *s)
                setstatus("error");
                while(!runq->iflag) Xreturn();
        }
       -void Xerror1(char *s)
       +
       +void
       +Xerror1(char *s)
        {
                if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
                        pfmt(err, "rc: %s\n", s);
       t@@ -799,150 +913,55 @@ void Xerror1(char *s)
                setstatus("error");
                while(!runq->iflag) Xreturn();
        }
       -void Xbackq(void){
       -        char wd[8193];
       -        int c;
       -        char *s, *ewd=&wd[8192], *stop;
       -        struct io *f;
       -        var *ifs=vlook("ifs");
       -        word *v, *nextv;
       -        int pfd[2];
       -        int pid;
       -        stop=ifs->val?ifs->val->word:"";
       -        if(pipe(pfd)<0){
       -                Xerror("can't make pipe");
       -                return;
       -        }
       -        switch(pid=fork()){
       -        case -1: Xerror("try again");
       -                close(pfd[PRD]);
       -                close(pfd[PWR]);
       -                return;
       -        case 0:
       -                close(pfd[PRD]);
       -                start(runq->code, runq->pc+1, runq->local);
       -                pushredir(ROPEN, pfd[PWR], 1);
       -                return;
       -        default:
       -                close(pfd[PWR]);
       -                f=openfd(pfd[PRD]);
       -                s=wd;
       -                v=0;
       -                while((c=rchr(f))!=EOF){
       -                        if(strchr(stop, c) || s==ewd){
       -                                if(s!=wd){
       -                                        *s='\0';
       -                                        v=newword(wd, v);
       -                                        s=wd;
       -                                }
       -                        }
       -                        else *s++=c;
       -                }
       -                if(s!=wd){
       -                        *s='\0';
       -                        v=newword(wd, v);
       -                }
       -                closeio(f);
       -                Waitfor(pid, 0);
       -                /* v points to reversed arglist -- reverse it onto argv */
       -                while(v){
       -                        nextv=v->next;
       -                        v->next=runq->argv->words;
       -                        runq->argv->words=v;
       -                        v=nextv;
       -                }
       -                runq->pc=runq->code[runq->pc].i;
       -                return;
       -        }
       -}
       -/*
       - * Who should wait for the exit from the fork?
       - */
       -void Xpipefd(void){
       -        struct thread *p=runq;
       -        int pc=p->pc;
       -        char name[40];
       -        int pfd[2];
       -        int sidefd, mainfd;
       -        if(pipe(pfd)<0){
       -                Xerror("can't get pipe");
       -                return;
       -        }
       -        if(p->code[pc].i==READ){
       -                sidefd=pfd[PWR];
       -                mainfd=pfd[PRD];
       -        }
       -        else{
       -                sidefd=pfd[PRD];
       -                mainfd=pfd[PWR];
       -        }
       -        switch(fork()){
       -        case -1:
       -                Xerror("try again");
       -                break;
       -        case 0:
       -                start(p->code, pc+2, runq->local);
       -                close(mainfd);
       -                pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
       -                runq->ret=0;
       -                break;
       -        default:
       -                close(sidefd);
       -                pushredir(ROPEN, mainfd, mainfd);        /* isn't this a noop? */
       -                strcpy(name, Fdprefix);
       -                itoa(name+strlen(name), mainfd);
       -                pushword(name);
       -                p->pc=p->code[pc+1].i;
       -                break;
       -        }
       -}
       -void Xsubshell(void){
       -        int pid;
       -        switch(pid=fork()){
       -        case -1:
       -                Xerror("try again");
       -                break;
       -        case 0:
       -                start(runq->code, runq->pc+1, runq->local);
       -                runq->ret=0;
       -                break;
       -        default:
       -                Waitfor(pid, 1);
       -                runq->pc=runq->code[runq->pc].i;
       -                break;
       -        }
       -}
       -void setstatus(char *s)
       +
       +void
       +setstatus(char *s)
        {
                setvar("status", newword(s, (word *)0));
        }
       -char *getstatus(void){
       -        var *status=vlook("status");
       +
       +char*
       +getstatus(void)
       +{
       +        var *status = vlook("status");
                return status->val?status->val->word:"";
        }
       -int truestatus(void){
       +
       +int
       +truestatus(void)
       +{
                char *s;
       -        for(s=getstatus();*s;s++)
       -                if(*s!='|' && *s!='0') return 0;
       +        for(s = getstatus();*s;s++)
       +                if(*s!='|' && *s!='0')
       +                        return 0;
                return 1;
        }
       -void Xdelhere(void){
       +
       +void
       +Xdelhere(void)
       +{
                Unlink(runq->code[runq->pc++].s);
        }
       -void Xfor(void){
       +
       +void
       +Xfor(void)
       +{
                if(runq->argv->words==0){
                        poplist();
       -                runq->pc=runq->code[runq->pc].i;
       +                runq->pc = runq->code[runq->pc].i;
                }
                else{
                        freelist(runq->local->val);
       -                runq->local->val=runq->argv->words;
       -                runq->local->changed=1;
       -                runq->argv->words=runq->argv->words->next;
       -                runq->local->val->next=0;
       +                runq->local->val = runq->argv->words;
       +                runq->local->changed = 1;
       +                runq->argv->words = runq->argv->words->next;
       +                runq->local->val->next = 0;
                        runq->pc++;
                }
        }
       -void Xglob(void){
       +
       +void
       +Xglob(void)
       +{
                globlist();
        }
 (DIR) diff --git a/src/cmd/rc/exec.h b/src/cmd/rc/exec.h
       t@@ -5,6 +5,7 @@ extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void)
        extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqdol(void), Xdup(void);
        extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void);
        extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void);
       +extern void Xrdwr(void);
        extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void);
        extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void);
        extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void);
       t@@ -51,7 +52,6 @@ struct thread{
                int iflag;                        /* interactive? */
                int lineno;                        /* linenumber */
                int pid;                        /* process for Xpipewait to wait for */
       -        int done;                        /* have we seen a wait message for this process? */
                char status[NSTATUS];                /* status for Xpipewait */
                tree *treenodes;                /* tree nodes created by this process */
                thread *ret;                /* who continues when this finishes */
       t@@ -61,12 +61,16 @@ code *codecopy(code*);
        code *codebuf;                                /* compiler output */
        int ntrap;                                /* number of outstanding traps */
        int trap[NSIG];                                /* number of outstanding traps per type */
       -extern struct builtin{
       +struct builtin{
                char *name;
                void (*fnc)(void);
       -}Builtin[];
       +};
       +extern struct builtin Builtin[];
        int eflagok;                        /* kludge flag so that -e doesn't exit in startup */
       +int havefork;
       +
        void execcd(void), execwhatis(void), execeval(void), execexec(void);
       +int execforkexec(void);
        void execexit(void), execshift(void);
        void execwait(void), execumask(void), execdot(void), execflag(void);
        void execfunc(var*), execcmds(io *);
 (DIR) diff --git a/src/cmd/rc/fns.h b/src/cmd/rc/fns.h
       t@@ -7,13 +7,14 @@ int        Eintr(void);
        int        Executable(char*);
        void        Execute(word*,  word*);
        void        Exit(char*);
       +int        ForkExecute(char*, char**, int, int, int);
        int        Globsize(char*);
        int        Isatty(int);
        void        Memcpy(char*, char*, long);
        void        Noerror(void);
        int        Opendir(char*);
        long        Read(int, char*, long);
       -int        Readdir(int, char*);
       +int        Readdir(int, char*, int);
        long        Seek(int, long, long);
        void        Trapinit(void);
        void        Unlink(char*);
       t@@ -27,7 +28,6 @@ void        cleanhere(char*);
        void        codefree(code*);
        int        compile(tree*);
        char *        list2str(word*);
       -char *        _list2str(word*, int);
        int        count(word*);
        void        deglob(char*);
        void        dotrap(void);
       t@@ -35,10 +35,12 @@ void        freenodes(void);
        void        freewords(word*);
        void        globlist(void);
        int        idchr(int);
       -void        itoa(char*, long);
       +void        inttoascii(char*, long);
        void        kinit(void);
       +int        mapfd(int);
        int        match(char*, char*, int);
        int        matchfn(char*, char*);
       +char**        mkargv(word*);
        void        panic(char*, int);
        void        pathinit(void);
        void        poplist(void);
       t@@ -48,9 +50,9 @@ void        pushlist(void);
        void        pushredir(int, int, int);
        void        pushword(char*);
        void        readhere(void);
       +word*        searchpath(char*);
        void        setstatus(char*);
        void        setvar(char*, word*);
       -void        _setvar(char*, word*, int);
        void        skipnl(void);
        void        start(code*, int, var*);
        int        truestatus(void);
 (DIR) diff --git a/src/cmd/rc/getflags.c b/src/cmd/rc/getflags.c
       t@@ -3,7 +3,7 @@
        #include "rc.h"
        #include "getflags.h"
        #include "fns.h"
       -char *flagset[]={"<flag>"};
       +char *flagset[] = {"<flag>"};
        char **flag[NFLAG];
        char cmdline[NCMDLINE+1];
        char *cmdname;
       t@@ -19,105 +19,118 @@ static int reason;
        #define        FLAGSYN        3
        #define        BADFLAG        4
        static int badflag;
       -int getflags(int argc, char *argv[], char *flags, int stop)
       +
       +int
       +getflags(int argc, char *argv[], char *flags, int stop)
        {
                char *s, *t;
                int i, j, c, count;
       -        flagarg=flags;
       -        if(cmdname==0) cmdname=argv[0];
       -        s=cmdline;
       -        for(i=0;i!=argc;i++){
       -                for(t=argv[i];*t;t++)
       +        flagarg = flags;
       +        if(cmdname==0)
       +                cmdname = argv[0];
       +        s = cmdline;
       +        for(i = 0;i!=argc;i++){
       +                for(t = argv[i];*t;t++)
                                if(s!=&cmdline[NCMDLINE])
                                        *s++=*t;
                        if(i!=argc-1 && s!=&cmdline[NCMDLINE])
                                *s++=' ';
                }
                *s='\0';
       -        i=1;
       +        i = 1;
                while(i!=argc){
                        if(argv[i][0]!='-' || argv[i][1]=='\0'){
       -                        if(stop) return argc;
       +                        if(stop)
       +                                return argc;
                                i++;
                                continue;
                        }
       -                s=argv[i]+1;
       +                s = argv[i]+1;
                        while(*s){
                                c=*s++;
       -                        count=scanflag(c, flags);
       -                        if(count==-1) return -1;
       -                        if(flag[c]){ reason=RESET; badflag=c; return -1; }
       +                        count = scanflag(c, flags);
       +                        if(count==-1)
       +                                return -1;
       +                        if(flag[c]){ reason = RESET; badflag = c; return -1; }
                                if(count==0){
       -                                flag[c]=flagset;
       +                                flag[c] = flagset;
                                        if(*s=='\0'){
       -                                        for(j=i+1;j<=argc;j++)
       -                                                argv[j-1]=argv[j];
       +                                        for(j = i+1;j<=argc;j++)
       +                                                argv[j-1] = argv[j];
                                                --argc;
                                        }
                                }
                                else{
                                        if(*s=='\0'){
       -                                        for(j=i+1;j<=argc;j++)
       -                                                argv[j-1]=argv[j];
       +                                        for(j = i+1;j<=argc;j++)
       +                                                argv[j-1] = argv[j];
                                                --argc;
       -                                        s=argv[i];
       +                                        s = argv[i];
                                        }
                                        if(argc-i<count){
       -                                        reason=FEWARGS;
       -                                        badflag=c;
       +                                        reason = FEWARGS;
       +                                        badflag = c;
                                                return -1;
                                        }
                                        reverse(argv+i, argv+argc);
                                        reverse(argv+i, argv+argc-count);
                                        reverse(argv+argc-count+1, argv+argc);
                                        argc-=count;
       -                                flag[c]=argv+argc+1;
       -                                flag[c][0]=s;
       +                                flag[c] = argv+argc+1;
       +                                flag[c][0] = s;
                                        s="";
                                }
                        }
                }
                return argc;
        }
       -static void reverse(char **p, char **q)
       +
       +static void
       +reverse(char **p, char **q)
        {
                char *t;
       -        for(;p<q;p++,--q){ t=*p; *p=*q; *q=t; }
       +        for(;p<q;p++,--q){ t=*p; *p=*q; *q = t; }
        }
       -static int scanflag(int c, char *f)
       +
       +static int
       +scanflag(int c, char *f)
        {
                int fc, count;
       -        if(0<=c && c<NFLAG) while(*f){
       -                if(*f==' '){
       -                        f++;
       -                        continue;
       -                }
       -                fc=*f++;
       -                if(*f==':'){
       -                        f++;
       -                        if(*f<'0' || '9'<*f){ reason=FLAGSYN; return -1; }
       -                        count=0;
       -                        while('0'<=*f && *f<='9') count=count*10+*f++-'0';
       -                }
       -                else
       -                        count=0;
       -                if(*f=='['){
       -                        do{
       +        if(0<=c && c<NFLAG)
       +                while(*f){
       +                        if(*f==' '){
       +                                f++;
       +                                continue;
       +                        }
       +                        fc=*f++;
       +                        if(*f==':'){
       +                                f++;
       +                                if(*f<'0' || '9'<*f){ reason = FLAGSYN; return -1; }
       +                                count = 0;
       +                                while('0'<=*f && *f<='9') count = count*10+*f++-'0';
       +                        }
       +                        else
       +                                count = 0;
       +                        if(*f=='['){
       +                                do{
       +                                        f++;
       +                                        if(*f=='\0'){ reason = FLAGSYN; return -1; }
       +                                }while(*f!=']');
                                        f++;
       -                                if(*f=='\0'){ reason=FLAGSYN; return -1; }
       -                        }while(*f!=']');
       -                        f++;
       +                        }
       +                        if(c==fc)
       +                                return count;
                        }
       -                if(c==fc) return count;
       -        }
       -        reason=BADFLAG;
       -        badflag=c;
       +        reason = BADFLAG;
       +        badflag = c;
                return -1;
        }
       -void usage(char *tail)
       +
       +void
       +usage(char *tail)
        {
                char *s, *t, c;
       -        int count, nflag=0;
       +        int count, nflag = 0;
                switch(reason){
                case RESET:
                        errs("Flag -");
       t@@ -140,46 +153,52 @@ void usage(char *tail)
                }
                errs("Usage: ");
                errs(cmdname);
       -        for(s=flagarg;*s;){
       +        for(s = flagarg;*s;){
                        c=*s;
       -                if(*s++==' ') continue;
       +                if(*s++==' ')
       +                        continue;
                        if(*s==':'){
                                s++;
       -                        count=0;
       -                        while('0'<=*s && *s<='9') count=count*10+*s++-'0';
       +                        count = 0;
       +                        while('0'<=*s && *s<='9') count = count*10+*s++-'0';
                        }
       -                else count=0;
       +                else count = 0;
                        if(count==0){
       -                        if(nflag==0) errs(" [-");
       +                        if(nflag==0)
       +                                errs(" [-");
                                nflag++;
                                errc(c);
                        }
                        if(*s=='['){
                                s++;
                                while(*s!=']' && *s!='\0') s++;
       -                        if(*s==']') s++;
       +                        if(*s==']')
       +                                s++;
                        }
                }
       -        if(nflag) errs("]");
       -        for(s=flagarg;*s;){
       +        if(nflag)
       +                errs("]");
       +        for(s = flagarg;*s;){
                        c=*s;
       -                if(*s++==' ') continue;
       +                if(*s++==' ')
       +                        continue;
                        if(*s==':'){
                                s++;
       -                        count=0;
       -                        while('0'<=*s && *s<='9') count=count*10+*s++-'0';
       +                        count = 0;
       +                        while('0'<=*s && *s<='9') count = count*10+*s++-'0';
                        }
       -                else count=0;
       +                else count = 0;
                        if(count!=0){
                                errs(" [-");
                                errc(c);
                                if(*s=='['){
                                        s++;
       -                                t=s;
       +                                t = s;
                                        while(*s!=']' && *s!='\0') s++;
                                        errs(" ");
                                        errn(t, s-t);
       -                                if(*s==']') s++;
       +                                if(*s==']')
       +                                        s++;
                                }
                                else
                                        while(count--) errs(" arg");
       t@@ -188,7 +207,8 @@ void usage(char *tail)
                        else if(*s=='['){
                                s++;
                                while(*s!=']' && *s!='\0') s++;
       -                        if(*s==']') s++;
       +                        if(*s==']')
       +                                s++;
                        }
                }
                if(tail){
       t@@ -198,20 +218,27 @@ void usage(char *tail)
                errs("\n");
                Exit("bad flags");
        }
       -static void errn(char *s, int count)
       +
       +static void
       +errn(char *s, int count)
        {
                while(count){ errc(*s++); --count; }
        }
       -static void errs(char *s)
       +
       +static void
       +errs(char *s)
        {
                while(*s) errc(*s++);
        }
        #define        NBUF        80
       -static char buf[NBUF], *bufp=buf;
       -static void errc(int c){
       +static char buf[NBUF], *bufp = buf;
       +
       +static void
       +errc(int c)
       +{
                *bufp++=c;
                if(bufp==&buf[NBUF] || c=='\n'){
                        Write(2, buf, bufp-buf);
       -                bufp=buf;
       +                bufp = buf;
                }
        }
 (DIR) diff --git a/src/cmd/rc/glob.c b/src/cmd/rc/glob.c
       t@@ -6,68 +6,77 @@ struct word *globv;
        /*
         * delete all the GLOB marks from s, in place
         */
       -void deglob(char *s)
       +
       +void
       +deglob(char *s)
        {
       -        char *t=s;
       +        char *t = s;
                do{
       -                if(*t==GLOB) t++;
       +                if(*t==GLOB)
       +                        t++;
                        *s++=*t;
                }while(*t++);
        }
       -int globcmp(const void *s, const void *t)
       +
       +int
       +globcmp(const void *s, const void *t)
        {
                return strcmp(*(char**)s, *(char**)t);
        }
       -void globsort(word *left, word *right)
       +
       +void
       +globsort(word *left, word *right)
        {
                char **list;
                word *a;
       -        int n=0;
       -        for(a=left;a!=right;a=a->next) n++;
       -        list=(char **)emalloc(n*sizeof(char *));
       -        for(a=left,n=0;a!=right;a=a->next,n++) list[n]=a->word;
       -        qsort((char *)list, n, sizeof(char *), globcmp);
       -        for(a=left,n=0;a!=right;a=a->next,n++) a->word=list[n];
       +        int n = 0;
       +        for(a = left;a!=right;a = a->next) n++;
       +        list = (char **)emalloc(n*sizeof(char *));
       +        for(a = left,n = 0;a!=right;a = a->next,n++) list[n] = a->word;
       +        qsort((void *)list, n, sizeof(void *), globcmp);
       +        for(a = left,n = 0;a!=right;a = a->next,n++) a->word = list[n];
                efree((char *)list);
        }
        /*
         * Push names prefixed by globname and suffixed by a match of p onto the astack.
         * namep points to the end of the prefix in globname.
         */
       -void globdir(char *p, char *namep)
       +
       +void
       +globdir(char *p, char *namep)
        {
                char *t, *newp;
                int f;
                /* scan the pattern looking for a component with a metacharacter in it */
                if(*p=='\0'){
       -                globv=newword(globname, globv);
       +                globv = newword(globname, globv);
                        return;
                }
       -        t=namep;
       -        newp=p;
       +        t = namep;
       +        newp = p;
                while(*newp){
                        if(*newp==GLOB)
                                break;
                        *t=*newp++;
                        if(*t++=='/'){
       -                        namep=t;
       -                        p=newp;
       +                        namep = t;
       +                        p = newp;
                        }
                }
                /* If we ran out of pattern, append the name if accessible */
                if(*newp=='\0'){
                        *t='\0';
                        if(access(globname, 0)==0)
       -                        globv=newword(globname, globv);
       +                        globv = newword(globname, globv);
                        return;
                }
                /* read the directory and recur for any entry that matches */
                *namep='\0';
       -        if((f=Opendir(globname[0]?globname:"."))<0) return;
       +        if((f = Opendir(globname[0]?globname:"."))<0) return;
                while(*newp!='/' && *newp!='\0') newp++;
       -        while(Readdir(f, namep)){
       +        while(Readdir(f, namep, *newp=='/')){
                        if(matchfn(namep, p)){
       -                        for(t=namep;*t;t++);
       +                        for(t = namep;*t;t++);
                                globdir(newp, t);
                        }
                }
       t@@ -77,22 +86,24 @@ void globdir(char *p, char *namep)
         * Push all file names matched by p on the current thread's stack.
         * If there are no matches, the list consists of p.
         */
       -void glob(char *p)
       +
       +void
       +glob(char *p)
        {
       -        word *svglobv=globv;
       -        int globlen=Globsize(p);
       +        word *svglobv = globv;
       +        int globlen = Globsize(p);
                if(!globlen){
                        deglob(p);
       -                globv=newword(p, globv);
       +                globv = newword(p, globv);
                        return;
                }
       -        globname=emalloc(globlen);
       +        globname = emalloc(globlen);
                globname[0]='\0';
                globdir(p, globname);
                efree(globname);
                if(svglobv==globv){
                        deglob(p);
       -                globv=newword(p, globv);
       +                globv = newword(p, globv);
                }
                else
                        globsort(globv, svglobv);
       t@@ -100,12 +111,18 @@ void glob(char *p)
        /*
         * Do p and q point at equal utf codes
         */
       -int equtf(char *p, char *q){
       -        if(*p!=*q) return 0;
       +
       +int
       +equtf(char *p, char *q)
       +{
       +        if(*p!=*q)
       +                return 0;
                if(twobyte(*p)) return p[1]==q[1];
                if(threebyte(*p)){
       -                if(p[1]!=q[1]) return 0;
       -                if(p[1]=='\0') return 1;        /* broken code at end of string! */
       +                if(p[1]!=q[1])
       +                        return 0;
       +                if(p[1]=='\0')
       +                        return 1;        /* broken code at end of string! */
                        return p[2]==q[2];
                }
                return 1;
       t@@ -114,7 +131,10 @@ int equtf(char *p, char *q){
         * Return a pointer to the next utf code in the string,
         * not jumping past nuls in broken utf codes!
         */
       -char *nextutf(char *p){
       +
       +char*
       +nextutf(char *p)
       +{
                if(twobyte(*p)) return p[1]=='\0'?p+1:p+2;
                if(threebyte(*p)) return p[1]=='\0'?p+1:p[2]=='\0'?p+2:p+3;
                return p+1;
       t@@ -122,7 +142,10 @@ char *nextutf(char *p){
        /*
         * Convert the utf code at *p to a unicode value
         */
       -int unicode(char *p){
       +
       +int
       +unicode(char *p)
       +{
                int u=*p&0xff;
                if(twobyte(u)) return ((u&0x1f)<<6)|(p[1]&0x3f);
                if(threebyte(u)) return (u<<12)|((p[1]&0x3f)<<6)|(p[2]&0x3f);
       t@@ -135,77 +158,97 @@ int unicode(char *p){
         * ? matches any single character
         * [...] matches the enclosed list of characters
         */
       -int matchfn(char *s, char *p)
       +
       +int
       +matchfn(char *s, char *p)
        {
                if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.')
                        return 0;
                return match(s, p, '/');
        }
       -int match(char *s, char *p, int stop)
       +
       +int
       +match(char *s, char *p, int stop)
        {
                int compl, hit, lo, hi, t, c;
       -        for(;*p!=stop && *p!='\0';s=nextutf(s),p=nextutf(p)){
       +        for(;*p!=stop && *p!='\0';s = nextutf(s),p = nextutf(p)){
                        if(*p!=GLOB){
                                if(!equtf(p, s)) return 0;
                        }
                        else switch(*++p){
                        case GLOB:
       -                        if(*s!=GLOB) return 0;
       +                        if(*s!=GLOB)
       +                                return 0;
                                break;
                        case '*':
                                for(;;){
                                        if(match(s, nextutf(p), stop)) return 1;
       -                                if(!*s) break;
       -                                s=nextutf(s);
       +                                if(!*s)
       +                                        break;
       +                                s = nextutf(s);
                                }
                                return 0;
                        case '?':
       -                        if(*s=='\0') return 0;
       +                        if(*s=='\0')
       +                                return 0;
                                break;
                        case '[':
       -                        if(*s=='\0') return 0;
       -                        c=unicode(s);
       +                        if(*s=='\0')
       +                                return 0;
       +                        c = unicode(s);
                                p++;
                                compl=*p=='~';
       -                        if(compl) p++;
       -                        hit=0;
       +                        if(compl)
       +                                p++;
       +                        hit = 0;
                                while(*p!=']'){
       -                                if(*p=='\0') return 0;                /* syntax error */
       -                                lo=unicode(p);
       -                                p=nextutf(p);
       -                                if(*p!='-') hi=lo;
       +                                if(*p=='\0')
       +                                        return 0;                /* syntax error */
       +                                lo = unicode(p);
       +                                p = nextutf(p);
       +                                if(*p!='-')
       +                                        hi = lo;
                                        else{
                                                p++;
       -                                        if(*p=='\0') return 0;        /* syntax error */
       -                                        hi=unicode(p);
       -                                        p=nextutf(p);
       -                                        if(hi<lo){ t=lo; lo=hi; hi=t; }
       +                                        if(*p=='\0')
       +                                                return 0;        /* syntax error */
       +                                        hi = unicode(p);
       +                                        p = nextutf(p);
       +                                        if(hi<lo){ t = lo; lo = hi; hi = t; }
                                        }
       -                                if(lo<=c && c<=hi) hit=1;
       +                                if(lo<=c && c<=hi)
       +                                        hit = 1;
                                }
       -                        if(compl) hit=!hit;
       -                        if(!hit) return 0;
       +                        if(compl)
       +                                hit=!hit;
       +                        if(!hit)
       +                                return 0;
                                break;
                        }
                }
                return *s=='\0';
        }
       -void globlist1(word *gl)
       +
       +void
       +globlist1(word *gl)
        {
                if(gl){
                        globlist1(gl->next);
                        glob(gl->word);
                }
        }
       -void globlist(void){
       +
       +void
       +globlist(void)
       +{
                word *a;
       -        globv=0;
       +        globv = 0;
                globlist1(runq->argv->words);
                poplist();
                pushlist();
                if(globv){
       -                for(a=globv;a->next;a=a->next);
       -                a->next=runq->argv->words;
       -                runq->argv->words=globv;
       +                for(a = globv;a->next;a = a->next);
       +                a->next = runq->argv->words;
       +                runq->argv->words = globv;
                }
        }
 (DIR) diff --git a/src/cmd/rc/havefork.c b/src/cmd/rc/havefork.c
       t@@ -1,5 +1,3 @@
       -#include <u.h>
       -#include <signal.h>
        #include "rc.h"
        #include "getflags.h"
        #include "exec.h"
       t@@ -13,9 +11,7 @@ Xasync(void)
        {
                int null = open("/dev/null", 0);
                int pid;
       -        int tcpgrp, pgrp;
                char npid[10];
       -
                if(null<0){
                        Xerror("Can't open /dev/null\n");
                        return;
       t@@ -26,12 +22,6 @@ Xasync(void)
                        Xerror("try again");
                        break;
                case 0:
       -                /*
       -                 * Should make reads of tty fail, writes succeed.
       -                 */
       -                signal(SIGTTIN, SIG_IGN);
       -                signal(SIGTTOU, SIG_IGN);
       -
                        pushredir(ROPEN, null, 0);
                        start(runq->code, runq->pc+1, runq->local);
                        runq->ret = 0;
 (DIR) diff --git a/src/cmd/rc/havep9p.c b/src/cmd/rc/havep9p.c
       t@@ -0,0 +1,246 @@
       +#include <u.h>
       +#include <signal.h>
       +#if defined(PLAN9PORT) && defined(__sun__)
       +#        define BSD_COMP        /* sigh.  for TIOCNOTTY */
       +#endif
       +#include <sys/ioctl.h>
       +#include "rc.h"
       +#include "getflags.h"
       +#include "exec.h"
       +#include "io.h"
       +#include "fns.h"
       +
       +int havefork = 1;
       +
       +void
       +Xasync(void)
       +{
       +        int null=open("/dev/null", 0);
       +        int tty;
       +        int pid;
       +        char npid[10];
       +        if(null<0){
       +                Xerror("Can't open /dev/null\n");
       +                return;
       +        }
       +        switch(pid=rfork(RFFDG|RFPROC|RFNOTEG)){
       +        case -1:
       +                close(null);
       +                Xerror("try again");
       +                break;
       +        case 0:
       +                /*
       +                 * I don't know what the right thing to do here is,
       +                 * so this is all experimentally determined.
       +                 * If we just dup /dev/null onto 0, then running
       +                 * ssh foo & will reopen /dev/tty, try to read a password,
       +                 * get a signal, and repeat, in a tight loop, forever.
       +                 * Arguably this is a bug in ssh (it behaves the same
       +                 * way under bash as under rc) but I'm fixing it here 
       +                 * anyway.  If we dissociate the process from the tty,
       +                 * then it won't be able to open /dev/tty ever again.
       +                 * The SIG_IGN on SIGTTOU makes writing the tty
       +                 * (via fd 1 or 2, for example) succeed even though 
       +                 * our pgrp is not the terminal's controlling pgrp.
       +                 */
       +                if((tty=open("/dev/tty", OREAD)) >= 0){
       +                        /*
       +                         * Should make reads of tty fail, writes succeed.
       +                         */
       +                        signal(SIGTTIN, SIG_IGN);
       +                        signal(SIGTTOU, SIG_IGN);
       +                        ioctl(tty, TIOCNOTTY);
       +                        close(tty);
       +                }
       +                if(isatty(0))
       +                        pushredir(ROPEN, null, 0);
       +                else
       +                        close(null);
       +                start(runq->code, runq->pc+1, runq->local);
       +                runq->ret=0;
       +                break;
       +        default:
       +                close(null);
       +                runq->pc=runq->code[runq->pc].i;
       +                inttoascii(npid, pid);
       +                setvar("apid", newword(npid, (word *)0));
       +                break;
       +        }
       +}
       +
       +void
       +Xpipe(void)
       +{
       +        struct thread *p = runq;
       +        int pc = p->pc, forkid;
       +        int lfd = p->code[pc++].i;
       +        int rfd = p->code[pc++].i;
       +        int pfd[2];
       +
       +        if(pipe(pfd)<0){
       +                Xerror("can't get pipe");
       +                return;
       +        }
       +        switch(forkid=fork()){
       +        case -1:
       +                Xerror("try again");
       +                break;
       +        case 0:
       +                start(p->code, pc+2, runq->local);
       +                runq->ret=0;
       +                close(pfd[PRD]);
       +                pushredir(ROPEN, pfd[PWR], lfd);
       +                break;
       +        default:
       +                start(p->code, p->code[pc].i, runq->local);
       +                close(pfd[PWR]);
       +                pushredir(ROPEN, pfd[PRD], rfd);
       +                p->pc=p->code[pc+1].i;
       +                p->pid=forkid;
       +                break;
       +        }
       +}
       +
       +void
       +Xbackq(void)
       +{
       +        char wd[8193];
       +        int c;
       +        char *s, *ewd = &wd[8192], *stop;
       +        struct io *f;
       +        var *ifs = vlook("ifs");
       +        word *v, *nextv;
       +        int pfd[2];
       +        int pid;
       +
       +        stop = ifs->val?ifs->val->word:"";
       +        if(pipe(pfd)<0){
       +                Xerror("can't make pipe");
       +                return;
       +        }
       +        switch(pid = fork()){
       +        case -1: Xerror("try again");
       +                close(pfd[PRD]);
       +                close(pfd[PWR]);
       +                return;
       +        case 0:
       +                close(pfd[PRD]);
       +                start(runq->code, runq->pc+1, runq->local);
       +                pushredir(ROPEN, pfd[PWR], 1);
       +                return;
       +        default:
       +                close(pfd[PWR]);
       +                f=openfd(pfd[PRD]);
       +                s=wd;
       +                v=0;
       +                while((c=rchr(f))!=EOF){
       +                        if(strchr(stop, c) || s==ewd){
       +                                if(s!=wd){
       +                                        *s='\0';
       +                                        v=newword(wd, v);
       +                                        s=wd;
       +                                }
       +                        }
       +                        else *s++=c;
       +                }
       +                if(s!=wd){
       +                        *s='\0';
       +                        v=newword(wd, v);
       +                }
       +                closeio(f);
       +                Waitfor(pid, 0);
       +                /* v points to reversed arglist -- reverse it onto argv */
       +                while(v){
       +                        nextv=v->next;
       +                        v->next=runq->argv->words;
       +                        runq->argv->words=v;
       +                        v=nextv;
       +                }
       +                runq->pc=runq->code[runq->pc].i;
       +                return;
       +        }
       +}
       +
       +/*
       + * Who should wait for the exit from the fork?
       + */
       +void
       +Xpipefd(void)
       +{
       +        struct thread *p=runq;
       +        int pc=p->pc;
       +        char name[40];
       +        int pfd[2];
       +        int sidefd, mainfd;
       +        if(pipe(pfd)<0){
       +                Xerror("can't get pipe");
       +                return;
       +        }
       +        if(p->code[pc].i==READ){
       +                sidefd=pfd[PWR];
       +                mainfd=pfd[PRD];
       +        }
       +        else{
       +                sidefd=pfd[PRD];
       +                mainfd=pfd[PWR];
       +        }
       +        switch(fork()){
       +        case -1:
       +                Xerror("try again");
       +                break;
       +        case 0:
       +                start(p->code, pc+2, runq->local);
       +                close(mainfd);
       +                pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
       +                runq->ret=0;
       +                break;
       +        default:
       +                close(sidefd);
       +                pushredir(ROPEN, mainfd, mainfd);        /* isn't this a noop? */
       +                strcpy(name, Fdprefix);
       +                inttoascii(name+strlen(name), mainfd);
       +                pushword(name);
       +                p->pc=p->code[pc+1].i;
       +                break;
       +        }
       +}
       +
       +void
       +Xsubshell(void)
       +{
       +        int pid;
       +        switch(pid=fork()){
       +        case -1:
       +                Xerror("try again");
       +                break;
       +        case 0:
       +                start(runq->code, runq->pc+1, runq->local);
       +                runq->ret=0;
       +                break;
       +        default:
       +                Waitfor(pid, 1);
       +                runq->pc=runq->code[runq->pc].i;
       +                break;
       +        }
       +}
       +
       +int
       +execforkexec(void)
       +{
       +        int pid;
       +        int n;
       +        char buf[ERRMAX];
       +
       +        switch(pid = fork()){
       +        case -1:
       +                return -1;
       +        case 0:
       +                pushword("exec");
       +                execexec();
       +                strcpy(buf, "can't exec: ");
       +                n = strlen(buf);
       +                errstr(buf+n, ERRMAX-n);
       +                Exit(buf);
       +        }
       +        return pid;
       +}
 (DIR) diff --git a/src/cmd/rc/here.c b/src/cmd/rc/here.c
       t@@ -3,32 +3,37 @@
        #include "io.h"
        #include "fns.h"
        struct here *here, **ehere;
       -int ser=0;
       +int ser = 0;
        char tmp[]="/tmp/here0000.0000";
        char hex[]="0123456789abcdef";
        void psubst(io*, char*);
        void pstrs(io*, word*);
       -void hexnum(char *p, int n)
       +
       +void
       +hexnum(char *p, int n)
        {
                *p++=hex[(n>>12)&0xF];
                *p++=hex[(n>>8)&0xF];
                *p++=hex[(n>>4)&0xF];
       -        *p=hex[n&0xF];
       +        *p = hex[n&0xF];
        }
       -tree *heredoc(tree *tag)
       +
       +tree*
       +heredoc(tree *tag)
        {
       -        struct here *h=new(struct here);
       -        if(tag->type!=WORD) yyerror("Bad here tag");
       -        h->next=0;
       +        struct here *h = new(struct here);
       +        if(tag->type!=WORD)
       +                yyerror("Bad here tag");
       +        h->next = 0;
                if(here)
       -                *ehere=h;
       +                *ehere = h;
                else
       -                here=h;
       +                here = h;
                ehere=&h->next;
       -        h->tag=tag;
       +        h->tag = tag;
                hexnum(&tmp[9], getpid());
                hexnum(&tmp[14], ser++);
       -        h->name=strdup(tmp);
       +        h->name = strdup(tmp);
                return token(tmp, WORD);
        }
        /*
       t@@ -36,27 +41,32 @@ tree *heredoc(tree *tag)
         * missubstitution, or a misrecognized EOF marker.
         */
        #define        NLINE        4096
       -void readhere(void){
       +
       +void
       +readhere(void)
       +{
                struct here *h, *nexth;
                io *f;
                char *s, *tag;
                int c, subst;
                char line[NLINE+1];
       -        for(h=here;h;h=nexth){
       +        for(h = here;h;h = nexth){
                        subst=!h->tag->quoted;
       -                tag=h->tag->str;
       -                c=Creat(h->name);
       -                if(c<0) yyerror("can't create here document");
       -                f=openfd(c);
       -                s=line;
       +                tag = h->tag->str;
       +                c = Creat(h->name);
       +                if(c<0)
       +                        yyerror("can't create here document");
       +                f = openfd(c);
       +                s = line;
                        pprompt();
       -                while((c=rchr(runq->cmdfd))!=EOF){
       +                while((c = rchr(runq->cmdfd))!=EOF){
                                if(c=='\n' || s==&line[NLINE]){
                                        *s='\0';
       -                                if(strcmp(line, tag)==0) break;
       -                                if(subst) psubst(f, line);
       +                                if(tag && strcmp(line, tag)==0) break;
       +                                if(subst)
       +                                        psubst(f, line);
                                        else pstr(f, line);
       -                                s=line;
       +                                s = line;
                                        if(c=='\n'){
                                                pprompt();
                                                pchr(f, c);
       t@@ -68,13 +78,15 @@ void readhere(void){
                        flush(f);
                        closeio(f);
                        cleanhere(h->name);
       -                nexth=h->next;
       +                nexth = h->next;
                        efree((char *)h);
                }
       -        here=0;
       -        doprompt=1;
       +        here = 0;
       +        doprompt = 1;
        }
       -void psubst(io *f, char *s)
       +
       +void
       +psubst(io *f, char *s)
        {
                char *t, *u;
                int savec, n;
       t@@ -83,48 +95,55 @@ void psubst(io *f, char *s)
                        if(*s!='$'){
                                if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){
                                        pchr(f, *s++);
       -                                if(*s=='\0') break;
       +                                if(*s=='\0')
       +                                        break;
                                }
                                else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){
                                        pchr(f, *s++);
       -                                if(*s=='\0') break;
       +                                if(*s=='\0')
       +                                        break;
                                        pchr(f, *s++);
       -                                if(*s=='\0') break;
       +                                if(*s=='\0')
       +                                        break;
                                }
                                pchr(f, *s++);
                        }
                        else{
                                t=++s;
       -                        if(*t=='$') pchr(f, *t++);
       +                        if(*t=='$')
       +                                pchr(f, *t++);
                                else{
                                        while(*t && idchr(*t)) t++;
                                        savec=*t;
                                        *t='\0';
       -                                n=0;
       -                                for(u=s;*u && '0'<=*u && *u<='9';u++) n=n*10+*u-'0';
       +                                n = 0;
       +                                for(u = s;*u && '0'<=*u && *u<='9';u++) n = n*10+*u-'0';
                                        if(n && *u=='\0'){
       -                                        star=vlook("*")->val;
       +                                        star = vlook("*")->val;
                                                if(star && 1<=n && n<=count(star)){
       -                                                while(--n) star=star->next;
       +                                                while(--n) star = star->next;
                                                        pstr(f, star->word);
                                                }
                                        }
                                        else
                                                pstrs(f, vlook(s)->val);
       -                                *t=savec;
       -                                if(savec=='^') t++;
       +                                *t = savec;
       +                                if(savec=='^')
       +                                        t++;
                                }
       -                        s=t;
       +                        s = t;
                        }
                }
        }
       -void pstrs(io *f, word *a)
       +
       +void
       +pstrs(io *f, word *a)
        {
                if(a){
                        while(a->next && a->next->word){
                                pstr(f, a->word);
                                pchr(f, ' ');
       -                        a=a->next;
       +                        a = a->next;
                        }
                        pstr(f, a->word);
                }
 (DIR) diff --git a/src/cmd/rc/io.c b/src/cmd/rc/io.c
       t@@ -2,68 +2,121 @@
        #include "exec.h"
        #include "io.h"
        #include "fns.h"
       -int pfmtnest=0;
       -void pfmt(io *f, char *fmt, ...){
       +int pfmtnest = 0;
       +
       +void
       +pfmt(io *f, char *fmt, ...)
       +{
                va_list ap;
                char err[ERRMAX];
                va_start(ap, fmt);
                pfmtnest++;
                for(;*fmt;fmt++)
       -                if(*fmt!='%') pchr(f, *fmt);
       +                if(*fmt!='%')
       +                        pchr(f, *fmt);
                        else switch(*++fmt){
       -                case '\0': va_end(ap); return;
       -                case 'c': pchr(f, va_arg(ap, int)); break;
       -                case 'd': pdec(f, va_arg(ap, int)); break;
       -                case 'o': poct(f, va_arg(ap, unsigned)); break;
       -                case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/
       -                case 'Q': pquo(f, va_arg(ap, char *)); break;
       -                case 'q': pwrd(f, va_arg(ap, char *)); break;
       -                case 'r': errstr(err, sizeof err); pstr(f, err); break;
       -                case 's': pstr(f, va_arg(ap, char *)); break;
       -                case 't': pcmd(f, va_arg(ap, struct tree *)); break;
       -                case 'v': pval(f, va_arg(ap, struct word *)); break;
       -                default: pchr(f, *fmt); break;
       +                case '\0':
       +                        va_end(ap);
       +                        return;
       +                case 'c':
       +                        pchr(f, va_arg(ap, int));
       +                        break;
       +                case 'd':
       +                        pdec(f, va_arg(ap, int));
       +                        break;
       +                case 'o':
       +                        poct(f, va_arg(ap, unsigned));
       +                        break;
       +                case 'p':
       +                        pptr(f, va_arg(ap, void*));
       +                        break;
       +                case 'Q':
       +                        pquo(f, va_arg(ap, char *));
       +                        break;
       +                case 'q':
       +                        pwrd(f, va_arg(ap, char *));
       +                        break;
       +                case 'r':
       +                        errstr(err, sizeof err); pstr(f, err);
       +                        break;
       +                case 's':
       +                        pstr(f, va_arg(ap, char *));
       +                        break;
       +                case 't':
       +                        pcmd(f, va_arg(ap, struct tree *));
       +                        break;
       +                case 'v':
       +                        pval(f, va_arg(ap, struct word *));
       +                        break;
       +                default:
       +                        pchr(f, *fmt);
       +                        break;
                        }
                va_end(ap);
       -        if(--pfmtnest==0) flush(f);
       +        if(--pfmtnest==0)
       +                flush(f);
        }
       -void pchr(io *b, int c)
       +
       +void
       +pchr(io *b, int c)
        {
       -        if(b->bufp==b->ebuf) fullbuf(b, c);
       +        if(b->bufp==b->ebuf)
       +                fullbuf(b, c);
                else *b->bufp++=c;
        }
       -int rchr(io *b)
       +
       +int
       +rchr(io *b)
        {
       -        if(b->bufp==b->ebuf) return emptybuf(b);
       +        if(b->bufp==b->ebuf)
       +                return emptybuf(b);
                return *b->bufp++ & 0xFF;
        }
        
       -void pquo(io *f, char *s)
       +void
       +pquo(io *f, char *s)
        {
                pchr(f, '\'');
                for(;*s;s++)
       -                if(*s=='\'') pfmt(f, "''");
       +                if(*s=='\'')
       +                        pfmt(f, "''");
                        else pchr(f, *s);
                pchr(f, '\'');
        }
       -void pwrd(io *f, char *s)
       +
       +void
       +pwrd(io *f, char *s)
        {
                char *t;
       -        for(t=s;*t;t++) if(!wordchr(*t)) break;
       -        if(t==s || *t) pquo(f, s);
       +        for(t = s;*t;t++) if(!wordchr(*t)) break;
       +        if(t==s || *t)
       +                pquo(f, s);
                else pstr(f, s);
        }
       -void phex(io *f, long p)
       +
       +void
       +pptr(io *f, void *v)
        {
                int n;
       -        for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
       +        uintptr p;
       +
       +        p = (uintptr)v;
       +        if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
       +                for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
       +
       +        for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
        }
       -void pstr(io *f, char *s)
       +
       +void
       +pstr(io *f, char *s)
        {
       -        if(s==0) s="(null)";
       +        if(s==0)
       +                s="(null)";
                while(*s) pchr(f, *s++);
        }
       -void pdec(io *f, long n)
       +
       +void
       +pdec(io *f, int n)
        {
                if(n<0){
                        n=-n;
       t@@ -73,110 +126,136 @@ void pdec(io *f, long n)
                                return;
                        }
                        /* n is two's complement minimum integer */
       -                n=1-n;
       +                n = 1-n;
                        pchr(f, '-');
                        pdec(f, n/10);
                        pchr(f, n%10+'1');
                        return;
                }
       -        if(n>9) pdec(f, n/10);
       +        if(n>9)
       +                pdec(f, n/10);
                pchr(f, n%10+'0');
        }
       -void poct(io *f, ulong n)
       +
       +void
       +poct(io *f, unsigned n)
        {
       -        if(n>7) poct(f, n>>3);
       +        if(n>7)
       +                poct(f, n>>3);
                pchr(f, (n&7)+'0');
        }
       -void pval(io *f, word *a)
       +
       +void
       +pval(io *f, word *a)
        {
                if(a){
                        while(a->next && a->next->word){
                                pwrd(f, a->word);
                                pchr(f, ' ');
       -                        a=a->next;
       +                        a = a->next;
                        }
                        pwrd(f, a->word);
                }
        }
       -int fullbuf(io *f, int c)
       +
       +int
       +fullbuf(io *f, int c)
        {
                flush(f);
                return *f->bufp++=c;
        }
       -void flush(io *f)
       +
       +void
       +flush(io *f)
        {
                int n;
                char *s;
                if(f->strp){
       -                n=f->ebuf-f->strp;
       -                f->strp=realloc(f->strp, n+101);
       -                if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101);
       -                f->bufp=f->strp+n;
       -                f->ebuf=f->bufp+100;
       -                for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
       +                n = f->ebuf-f->strp;
       +                f->strp = realloc(f->strp, n+101);
       +                if(f->strp==0)
       +                        panic("Can't realloc %d bytes in flush!", n+101);
       +                f->bufp = f->strp+n;
       +                f->ebuf = f->bufp+100;
       +                for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
                }
                else{
       -                n=f->bufp-f->buf;
       +                n = f->bufp-f->buf;
                        if(n && Write(f->fd, f->buf, n) < 0){
                                Write(3, "Write error\n", 12);
       -                        if(ntrap) dotrap();
       +                        if(ntrap)
       +                                dotrap();
                        }
       -                f->bufp=f->buf;
       -                f->ebuf=f->buf+NBUF;
       +                f->bufp = f->buf;
       +                f->ebuf = f->buf+NBUF;
                }
        }
       -io *openfd(int fd){
       -        io *f;
       -        f=new(struct io);
       -        f->fd=fd;
       -        f->bufp=f->ebuf=f->buf;
       -        f->strp=0;
       +
       +io*
       +openfd(int fd)
       +{
       +        io *f = new(struct io);
       +        f->fd = fd;
       +        f->bufp = f->ebuf = f->buf;
       +        f->strp = 0;
                return f;
        }
       -io *openstr(void){
       -        io *f=new(struct io);
       +
       +io*
       +openstr(void)
       +{
       +        io *f = new(struct io);
                char *s;
                f->fd=-1;
       -        f->bufp=f->strp=emalloc(101);
       -        f->ebuf=f->bufp+100;
       -        for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
       +        f->bufp = f->strp = emalloc(101);
       +        f->ebuf = f->bufp+100;
       +        for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
                return f;
        }
        /*
         * Open a corebuffer to read.  EOF occurs after reading len
         * characters from buf.
         */
       -io *opencore(char *s, int len)
       +
       +io*
       +opencore(char *s, int len)
        {
       -        io *f=new(struct io);
       -        char *buf=emalloc(len);
       +        io *f = new(struct io);
       +        char *buf = emalloc(len);
                f->fd= -1 /*open("/dev/null", 0)*/;
       -        f->bufp=f->strp=buf;
       -        f->ebuf=buf+len;
       +        f->bufp = f->strp = buf;
       +        f->ebuf = buf+len;
                Memcpy(buf, s, len);
                return f;
        }
       -/*
       -void rewind(io *io)
       +
       +void
       +rewind(io *io)
        {
       -        if(io->fd==-1) io->bufp=io->strp;
       +        if(io->fd==-1)
       +                io->bufp = io->strp;
                else{
       -                io->bufp=io->ebuf=io->buf;
       +                io->bufp = io->ebuf = io->buf;
                        Seek(io->fd, 0L, 0);
                }
        }
       -*/
       -void closeio(io *io)
       +
       +void
       +closeio(io *io)
        {
       -        if(io->fd>=0) close(io->fd);
       -        if(io->strp) efree(io->strp);
       +        if(io->fd>=0)
       +                close(io->fd);
       +        if(io->strp)
       +                efree(io->strp);
                efree((char *)io);
        }
       -int emptybuf(io *f)
       +
       +int
       +emptybuf(io *f)
        {
                int n;
       -        if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF;
       -        f->bufp=f->buf;
       -        f->ebuf=f->buf+n;
       +        if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
       +        f->bufp = f->buf;
       +        f->ebuf = f->buf+n;
                return *f->bufp++&0xff;
        }
 (DIR) diff --git a/src/cmd/rc/io.h b/src/cmd/rc/io.h
       t@@ -18,9 +18,9 @@ int rchr(io*);
        void closeio(io*);
        void flush(io*);
        int fullbuf(io*, int);
       -void pdec(io*, long);
       -void poct(io*, ulong);
       -void phex(io*, long);
       +void pdec(io*, int);
       +void poct(io*, unsigned);
       +void pptr(io*, void*);
        void pquo(io*, char*);
        void pwrd(io*, char*);
        void pstr(io*, char*);
 (DIR) diff --git a/src/cmd/rc/lex.c b/src/cmd/rc/lex.c
       t@@ -4,11 +4,15 @@
        #include "getflags.h"
        #include "fns.h"
        int getnext(void);
       -int wordchr(int c)
       +
       +int
       +wordchr(int c)
        {
                return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF;
        }
       -int idchr(int c)
       +
       +int
       +idchr(int c)
        {
                /*
                 * Formerly:
       t@@ -17,127 +21,170 @@ int idchr(int c)
                 */
                return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c);
        }
       -int future=EOF;
       -int doprompt=1;
       +int future = EOF;
       +int doprompt = 1;
        int inquote;
       +int incomm;
        /*
         * Look ahead in the input stream
         */
       -int nextc(void){
       -        if(future==EOF) future=getnext();
       +
       +int
       +nextc(void)
       +{
       +        if(future==EOF)
       +                future = getnext();
                return future;
        }
        /*
         * Consume the lookahead character.
         */
       -int advance(void){
       -        int c=nextc();
       -        lastc=future;
       -        future=EOF;
       +
       +int
       +advance(void)
       +{
       +        int c = nextc();
       +        lastc = future;
       +        future = EOF;
                return c;
        }
        /*
         * read a character from the input stream
         */        
       -int getnext(void){
       -        register int c;
       -        static int peekc=EOF;
       +
       +int
       +getnext(void)
       +{
       +        int c;
       +        static int peekc = EOF;
                if(peekc!=EOF){
       -                c=peekc;
       -                peekc=EOF;
       +                c = peekc;
       +                peekc = EOF;
                        return c;
                }
       -        if(runq->eof) return EOF;
       -        if(doprompt) pprompt();
       -        c=rchr(runq->cmdfd);
       +        if(runq->eof)
       +                return EOF;
       +        if(doprompt)
       +                pprompt();
       +        c = rchr(runq->cmdfd);
                if(!inquote && c=='\\'){
       -                c=rchr(runq->cmdfd);
       -                if(c=='\n'){
       -                        doprompt=1;
       +                c = rchr(runq->cmdfd);
       +                if(c=='\n' && !incomm){                /* don't continue a comment */
       +                        doprompt = 1;
                                c=' ';
                        }
                        else{
       -                        peekc=c;
       +                        peekc = c;
                                c='\\';
                        }
                }
       -        doprompt=doprompt || c=='\n' || c==EOF;
       -        if(c==EOF) runq->eof++;
       +        doprompt = doprompt || c=='\n' || c==EOF;
       +        if(c==EOF)
       +                runq->eof++;
                else if(flag['V'] || ndot>=2 && flag['v']) pchr(err, c);
                return c;
        }
       -void pprompt(void){
       +
       +void
       +pprompt(void)
       +{
                var *prompt;
                if(runq->iflag){
                        pstr(err, promptstr);
                        flush(err);
       -                prompt=vlook("prompt");
       +                prompt = vlook("prompt");
                        if(prompt->val && prompt->val->next)
       -                        promptstr=prompt->val->next->word;
       +                        promptstr = prompt->val->next->word;
                        else
                                promptstr="\t";
                }
                runq->lineno++;
       -        doprompt=0;
       +        doprompt = 0;
        }
       -void skipwhite(void){
       +
       +void
       +skipwhite(void)
       +{
                int c;
                for(;;){
       -                c=nextc();
       -                if(c=='#'){        /* Why did this used to be  if(!inquote && c=='#') ?? */
       +                c = nextc();
       +                /* Why did this used to be  if(!inquote && c=='#') ?? */
       +                if(c=='#'){
       +                        incomm = 1;
                                for(;;){
       -                                c=nextc();
       -                                if(c=='\n' || c==EOF) break;
       +                                c = nextc();
       +                                if(c=='\n' || c==EOF) {
       +                                        incomm = 0;
       +                                        break;
       +                                }
                                        advance();
                                }
                        }
       -                if(c==' ' || c=='\t') advance();
       +                if(c==' ' || c=='\t')
       +                        advance();
                        else return;
                }
        }
       -void skipnl(void){
       -        register int c;
       +
       +void
       +skipnl(void)
       +{
       +        int c;
                for(;;){
                        skipwhite();
       -                c=nextc();
       -                if(c!='\n') return;
       +                c = nextc();
       +                if(c!='\n')
       +                        return;
                        advance();
                }
        }
       -int nextis(int c){
       +
       +int
       +nextis(int c)
       +{
                if(nextc()==c){
                        advance();
                        return 1;
                }
                return 0;
        }
       -char *addtok(char *p, int val){
       -        if(p==0) return 0;
       +
       +char*
       +addtok(char *p, int val)
       +{
       +        if(p==0)
       +                return 0;
                if(p==&tok[NTOK-1]){
       -                *p=0;
       +                *p = 0;
                        yyerror("token buffer too short");
                        return 0;
                }
                *p++=val;
                return p;
        }
       -char *addutf(char *p, int c){
       -        p=addtok(p, c);
       +
       +char*
       +addutf(char *p, int c)
       +{
       +        p = addtok(p, c);
                if(twobyte(c))         /* 2-byte escape */
                        return addtok(p, advance());
                if(threebyte(c)){        /* 3-byte escape */
       -                p=addtok(p, advance());
       +                p = addtok(p, advance());
                        return addtok(p, advance());
                }
                return p;
        }
        int lastdol;        /* was the last token read '$' or '$#' or '"'? */
        int lastword;        /* was the last token read a word or compound word terminator? */
       -int yylex(void){
       -        register int c, d=nextc();
       -        register char *w=tok;
       -        register struct tree *t;
       -        yylval.tree=0;
       +
       +int
       +yylex(void)
       +{
       +        int c, d = nextc();
       +        char *w = tok;
       +        struct tree *t;
       +        yylval.tree = 0;
                /*
                 * Embarassing sneakiness:  if the last token read was a quoted or unquoted
                 * WORD then we alter the meaning of what follows.  If the next character
       t@@ -146,7 +193,7 @@ int yylex(void){
                 * we insert a `^' before it.
                 */
                if(lastword){
       -                lastword=0;
       +                lastword = 0;
                        if(d=='('){
                                advance();
                                strcpy(tok, "( [SUB]");
       t@@ -157,15 +204,15 @@ int yylex(void){
                                return '^';
                        }
                }
       -        inquote=0;
       +        inquote = 0;
                skipwhite();
       -        switch(c=advance()){
       +        switch(c = advance()){
                case EOF:
       -                lastdol=0;
       +                lastdol = 0;
                        strcpy(tok, "EOF");
                        return EOF;
                case '$':
       -                lastdol=1;
       +                lastdol = 1;
                        if(nextis('#')){
                                strcpy(tok, "$#");
                                return COUNT;
       t@@ -177,7 +224,7 @@ int yylex(void){
                        strcpy(tok, "$");
                        return '$';
                case '&':
       -                lastdol=0;
       +                lastdol = 0;
                        if(nextis('&')){
                                skipnl();
                                strcpy(tok, "&&");
       t@@ -186,7 +233,7 @@ int yylex(void){
                        strcpy(tok, "&");
                        return '&';
                case '|':
       -                lastdol=0;
       +                lastdol = 0;
                        if(nextis(c)){
                                skipnl();
                                strcpy(tok, "||");
       t@@ -194,7 +241,7 @@ int yylex(void){
                        }
                case '<':
                case '>':
       -                lastdol=0;
       +                lastdol = 0;
                        /*
                         * funny redirection tokens:
                         *        redir:        arrow | arrow '[' fd ']'
       t@@ -204,121 +251,128 @@ int yylex(void){
                         * some possibilities are nonsensical and get a message.
                         */
                        *w++=c;
       -                t=newtree();
       +                t = newtree();
                        switch(c){
                        case '|':
       -                        t->type=PIPE;
       -                        t->fd0=1;
       -                        t->fd1=0;
       +                        t->type = PIPE;
       +                        t->fd0 = 1;
       +                        t->fd1 = 0;
                                break;
                        case '>':
       -                        t->type=REDIR;
       +                        t->type = REDIR;
                                if(nextis(c)){
       -                                t->rtype=APPEND;
       +                                t->rtype = APPEND;
                                        *w++=c;
                                }
       -                        else t->rtype=WRITE;
       -                        t->fd0=1;
       +                        else t->rtype = WRITE;
       +                        t->fd0 = 1;
                                break;
                        case '<':
       -                        t->type=REDIR;
       +                        t->type = REDIR;
                                if(nextis(c)){
       -                                t->rtype=HERE;
       +                                t->rtype = HERE;
                                        *w++=c;
       -                        }
       -                        else t->rtype=READ;
       -                        t->fd0=0;
       +                        } else if (nextis('>')){
       +                                t->rtype = RDWR;
       +                                *w++=c;
       +                        } else t->rtype = READ;
       +                        t->fd0 = 0;
                                break;
                        }
                        if(nextis('[')){
                                *w++='[';
       -                        c=advance();
       +                        c = advance();
       +                        *w++=c;
                                if(c<'0' || '9'<c){
                                RedirErr:
       -                                *w++ = c;
       -                                *w=0;
       +                                *w = 0;
                                        yyerror(t->type==PIPE?"pipe syntax"
                                                        :"redirection syntax");
                                        return EOF;
                                }
       -                        t->fd0=0;
       +                        t->fd0 = 0;
                                do{
       -                                t->fd0=t->fd0*10+c-'0';
       +                                t->fd0 = t->fd0*10+c-'0';
                                        *w++=c;
       -                                c=advance();
       +                                c = advance();
                                }while('0'<=c && c<='9');
                                if(c=='='){
                                        *w++='=';
       -                                if(t->type==REDIR) t->type=DUP;
       -                                c=advance();
       +                                if(t->type==REDIR)
       +                                        t->type = DUP;
       +                                c = advance();
                                        if('0'<=c && c<='9'){
       -                                        t->rtype=DUPFD;
       -                                        t->fd1=t->fd0;
       -                                        t->fd0=0;
       +                                        t->rtype = DUPFD;
       +                                        t->fd1 = t->fd0;
       +                                        t->fd0 = 0;
                                                do{
       -                                                t->fd0=t->fd0*10+c-'0';
       +                                                t->fd0 = t->fd0*10+c-'0';
                                                        *w++=c;
       -                                                c=advance();
       +                                                c = advance();
                                                }while('0'<=c && c<='9');
                                        }
                                        else{
       -                                        if(t->type==PIPE) goto RedirErr;
       -                                        t->rtype=CLOSE;
       +                                        if(t->type==PIPE)
       +                                                goto RedirErr;
       +                                        t->rtype = CLOSE;
                                        }
                                }
       -                        *w=0;
                                if(c!=']'
                                || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND))
                                        goto RedirErr;
                                *w++=']';
                        }
                        *w='\0';
       -                yylval.tree=t;
       -                if(t->type==PIPE) skipnl();
       +                yylval.tree = t;
       +                if(t->type==PIPE)
       +                        skipnl();
                        return t->type;
                case '\'':
       -                lastdol=0;
       -                lastword=1;
       -                inquote=1;
       +                lastdol = 0;
       +                lastword = 1;
       +                inquote = 1;
                        for(;;){
       -                        c=advance();
       -                        if(c==EOF) break;
       +                        c = advance();
       +                        if(c==EOF)
       +                                break;
                                if(c=='\''){
                                        if(nextc()!='\'')
                                                break;
                                        advance();
                                }
       -                        w=addutf(w, c);
       +                        w = addutf(w, c);
                        }
       -                if(w!=0) *w='\0';
       -                t=token(tok, WORD);
       -                t->quoted=1;
       -                yylval.tree=t;
       +                if(w!=0)
       +                        *w='\0';
       +                t = token(tok, WORD);
       +                t->quoted = 1;
       +                yylval.tree = t;
                        return t->type;
                }
                if(!wordchr(c)){
       -                lastdol=0;
       -                tok[0]=c;
       +                lastdol = 0;
       +                tok[0] = c;
                        tok[1]='\0';
                        return c;
                }
                for(;;){
                        /* next line should have (char)c==GLOB, but ken's compiler is broken */
                        if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB)
       -                        w=addtok(w, GLOB);
       -                w=addutf(w, c);
       -                c=nextc();
       +                        w = addtok(w, GLOB);
       +                w = addutf(w, c);
       +                c = nextc();
                        if(lastdol?!idchr(c):!wordchr(c)) break;
                        advance();
                }
        
       -        lastword=1;
       -        lastdol=0;
       -        if(w!=0) *w='\0';
       -        t=klook(tok);
       -        if(t->type!=WORD) lastword=0;
       -        t->quoted=0;
       -        yylval.tree=t;
       +        lastword = 1;
       +        lastdol = 0;
       +        if(w!=0)
       +                *w='\0';
       +        t = klook(tok);
       +        if(t->type!=WORD)
       +                lastword = 0;
       +        t->quoted = 0;
       +        yylval.tree = t;
                return t->type;
        }
       -
 (DIR) diff --git a/src/cmd/rc/mkfile b/src/cmd/rc/mkfile
       t@@ -20,6 +20,7 @@ OFILES=\
                var.$O\
                y.tab.$O\
                plan9ish.$O\
       +        havep9p.$O\
        
        HFILES=\
                rc.h\
 (DIR) diff --git a/src/cmd/rc/pcmd.c b/src/cmd/rc/pcmd.c
       t@@ -5,39 +5,66 @@ char nl='\n';                /* change to semicolon for bourne-proofing */
        #define        c0        t->child[0]
        #define        c1        t->child[1]
        #define        c2        t->child[2]
       -void pdeglob(io *f, char *s)
       +
       +void
       +pdeglob(io *f, char *s)
        {
                while(*s){
       -                if(*s==GLOB) s++;
       +                if(*s==GLOB)
       +                        s++;
                        pchr(f, *s++);
                }
        }
       -void pcmd(io *f, tree *t)
       +
       +void
       +pcmd(io *f, tree *t)
        {
       -        if(t==0) return;
       +        if(t==0)
       +                return;
                switch(t->type){
       -        default:        pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); break;
       -        case '$':        pfmt(f, "$%t", c0); break;
       -        case '"':        pfmt(f, "$\"%t", c0); break;
       -        case '&':        pfmt(f, "%t&", c0); break;
       -        case '^':        pfmt(f, "%t^%t", c0, c1); break;
       -        case '`':        pfmt(f, "`%t", c0); break;
       -        case ANDAND:        pfmt(f, "%t && %t", c0, c1); break;
       -        case BANG:        pfmt(f, "! %t", c0); break;
       -        case BRACE:        pfmt(f, "{%t}", c0); break;
       -        case COUNT:        pfmt(f, "$#%t", c0); break;
       -        case FN:        pfmt(f, "fn %t %t", c0, c1); break;
       -        case IF:        pfmt(f, "if%t%t", c0, c1); break;
       -        case NOT:        pfmt(f, "if not %t", c0); break;
       -        case OROR:        pfmt(f, "%t || %t", c0, c1); break;
       +        default:        pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2);
       +        break;
       +        case '$':        pfmt(f, "$%t", c0);
       +        break;
       +        case '"':        pfmt(f, "$\"%t", c0);
       +        break;
       +        case '&':        pfmt(f, "%t&", c0);
       +        break;
       +        case '^':        pfmt(f, "%t^%t", c0, c1);
       +        break;
       +        case '`':        pfmt(f, "`%t", c0);
       +        break;
       +        case ANDAND:        pfmt(f, "%t && %t", c0, c1);
       +        break;
       +        case BANG:        pfmt(f, "! %t", c0);
       +        break;
       +        case BRACE:        pfmt(f, "{%t}", c0);
       +        break;
       +        case COUNT:        pfmt(f, "$#%t", c0);
       +        break;
       +        case FN:        pfmt(f, "fn %t %t", c0, c1);
       +        break;
       +        case IF:        pfmt(f, "if%t%t", c0, c1);
       +        break;
       +        case NOT:        pfmt(f, "if not %t", c0);
       +        break;
       +        case OROR:        pfmt(f, "%t || %t", c0, c1);
       +        break;
                case PCMD:
       -        case PAREN:        pfmt(f, "(%t)", c0); break;
       -        case SUB:        pfmt(f, "$%t(%t)", c0, c1); break;
       -        case SIMPLE:        pfmt(f, "%t", c0); break;
       -        case SUBSHELL:        pfmt(f, "@ %t", c0); break;
       -        case SWITCH:        pfmt(f, "switch %t %t", c0, c1); break;
       -        case TWIDDLE:        pfmt(f, "~ %t %t", c0, c1); break;
       -        case WHILE:        pfmt(f, "while %t%t", c0, c1); break;
       +        case PAREN:        pfmt(f, "(%t)", c0);
       +        break;
       +        case SUB:        pfmt(f, "$%t(%t)", c0, c1);
       +        break;
       +        case SIMPLE:        pfmt(f, "%t", c0);
       +        break;
       +        case SUBSHELL:        pfmt(f, "@ %t", c0);
       +        break;
       +        case SWITCH:        pfmt(f, "switch %t %t", c0, c1);
       +        break;
       +        case TWIDDLE:        pfmt(f, "~ %t %t", c0, c1);
       +        break;
       +        case WHILE:        pfmt(f, "while %t%t", c0, c1);
       +        break;
                case ARGLIST:
                        if(c0==0)
                                pfmt(f, "%t", c1);
       t@@ -48,22 +75,26 @@ void pcmd(io *f, tree *t)
                        break;
                case ';':
                        if(c0){
       -                        if(c1) pfmt(f, "%t%c%t", c0, nl, c1);
       +                        if(c1)
       +                                pfmt(f, "%t%c%t", c0, nl, c1);
                                else pfmt(f, "%t", c0);
                        }
                        else pfmt(f, "%t", c1);
                        break;
                case WORDS:
       -                if(c0) pfmt(f, "%t ", c0);
       +                if(c0)
       +                        pfmt(f, "%t ", c0);
                        pfmt(f, "%t", c1);
                        break;
                case FOR:
                        pfmt(f, "for(%t", c0);
       -                if(c1) pfmt(f, " in %t", c1);
       +                if(c1)
       +                        pfmt(f, " in %t", c1);
                        pfmt(f, ")%t", c2);
                        break;
                case WORD:
       -                if(t->quoted) pfmt(f, "%Q", t->str);
       +                if(t->quoted)
       +                        pfmt(f, "%Q", t->str);
                        else pdeglob(f, t->str);
                        break;
                case DUP:
       t@@ -79,27 +110,35 @@ void pcmd(io *f, tree *t)
                        case HERE:
                                pchr(f, '<');
                        case READ:
       +                case RDWR:
                                pchr(f, '<');
       -                        if(t->fd0!=0) pfmt(f, "[%d]", t->fd0);
       +                        if(t->rtype==RDWR)
       +                                pchr(f, '>');
       +                        if(t->fd0!=0)
       +                                pfmt(f, "[%d]", t->fd0);
                                break;
                        case APPEND:
                                pchr(f, '>');
                        case WRITE:
                                pchr(f, '>');
       -                        if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
       +                        if(t->fd0!=1)
       +                                pfmt(f, "[%d]", t->fd0);
                                break;
                        }
                        pfmt(f, "%t", c0);
       -                if(c1) pfmt(f, " %t", c1);
       +                if(c1)
       +                        pfmt(f, " %t", c1);
                        break;
                case '=':
                        pfmt(f, "%t=%t", c0, c1);
       -                if(c2) pfmt(f, " %t", c2);
       +                if(c2)
       +                        pfmt(f, " %t", c2);
                        break;
                case PIPE:
                        pfmt(f, "%t|", c0);
                        if(t->fd1==0){
       -                        if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
       +                        if(t->fd0!=1)
       +                                pfmt(f, "[%d]", t->fd0);
                        }
                        else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
                        pfmt(f, "%t", c1);
 (DIR) diff --git a/src/cmd/rc/pfnc.c b/src/cmd/rc/pfnc.c
       t@@ -5,7 +5,7 @@
        struct{
                void (*f)(void);
                char *name;
       -}fname[]={
       +}fname[] = {
                Xappend, "Xappend",
                Xasync, "Xasync",
                Xbang, "Xbang",
       t@@ -18,6 +18,7 @@ struct{
                Xjump, "Xjump",
                Xmark, "Xmark",
                Xpopm, "Xpopm",
       +        Xrdwr, "Xrdwr",
                Xread, "Xread",
                Xreturn, "Xreturn",
                Xtrue, "Xtrue",
       t@@ -50,18 +51,21 @@ struct{
                Xrdfn, "Xrdfn",
                Xqdol, "Xqdol",
        0};
       -void pfnc(io *fd, thread *t)
       +
       +void
       +pfnc(io *fd, thread *t)
        {
                int i;
       -        void (*fn)(void)=t->code[t->pc].f;
       +        void (*fn)(void) = t->code[t->pc].f;
                list *a;
                pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc);
       -        for(i=0;fname[i].f;i++) if(fname[i].f==fn){
       +        for(i = 0;fname[i].f;i++) if(fname[i].f==fn){
                        pstr(fd, fname[i].name);
                        break;
                }
       -        if(!fname[i].f) pfmt(fd, "%p", fn);
       -        for(a=t->argv;a;a=a->next) pfmt(fd, " (%v)", a->words);
       +        if(!fname[i].f)
       +                pfmt(fd, "%p", fn);
       +        for(a = t->argv;a;a = a->next) pfmt(fd, " (%v)", a->words);
                pchr(fd, '\n');
                flush(fd);
        }
 (DIR) diff --git a/src/cmd/rc/plan9ish.c b/src/cmd/rc/plan9ish.c
       t@@ -411,9 +411,11 @@ int Opendir(char *name)
                close(f);
                return -1;
        }
       -int Readdir(int f, char *p)
       +int Readdir(int f, char *p, int onlydirs)
        {
                int n;
       +        USED(onlydirs);        /* only advisory */
       +
                if(f<0 || f>=NFD)
                        return 0;
                if(dir[f].i==dir[f].n){        /* read */
 (DIR) diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h
       t@@ -80,6 +80,7 @@ char tok[NTOK];
        #define        HERE        4
        #define        DUPFD        5
        #define        CLOSE        6
       +#define        RDWR        7
        struct var{
                char *name;                /* ascii name */
                word *val;        /* value */
 (DIR) diff --git a/src/cmd/rc/simple.c b/src/cmd/rc/simple.c
       t@@ -15,22 +15,24 @@ exitnext(void){
                while(c->f==Xpopredir) c++;
                return c->f==Xexit;
        }
       -void Xsimple(void){
       +
       +void
       +Xsimple(void)
       +{
                word *a;
       -        thread *p=runq;
       +        thread *p = runq;
                var *v;
                struct builtin *bp;
       -        int pid, n;
       -        char buf[ERRMAX];
       +        int pid;
                globlist();
       -        a=runq->argv->words;
       +        a = runq->argv->words;
                if(a==0){
                        Xerror1("empty argument list");
                        return;
                }
                if(flag['x'])
                        pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
       -        v=gvlook(a->word);
       +        v = gvlook(a->word);
                if(v->fn)
                        execfunc(v);
                else{
       t@@ -41,10 +43,10 @@ void Xsimple(void){
                                        poplist();
                                        return;
                                }
       -                        a=a->next;
       +                        a = a->next;
                                popword();
                        }
       -                for(bp=Builtin;bp->name;bp++)
       +                for(bp = Builtin;bp->name;bp++)
                                if(strcmp(a->word, bp->name)==0){
                                        (*bp->fnc)();
                                        return;
       t@@ -58,30 +60,22 @@ void Xsimple(void){
                        else{
                                flush(err);
                                Updenv();        /* necessary so changes don't go out again */
       -                        switch(pid=fork()){
       -                        case -1:
       +                        if((pid = execforkexec()) < 0){
                                        Xerror("try again");
                                        return;
       -                        case 0:
       -                                pushword("exec");
       -                                execexec();
       -                                strcpy(buf, "can't exec: ");
       -                                n = strlen(buf);
       -                                errstr(buf+n, ERRMAX-n);
       -                                Exit(buf);
       -                        default:
       -                                kidpid = pid;
       -                                poplist();
       -                                /* interrupts don't get us out */
       -                                while(Waitfor(pid, 1) < 0)
       -                                        ;
       -                                kidpid = 0;
                                }
       +
       +                        /* interrupts don't get us out */
       +                        poplist();
       +                        while(Waitfor(pid, 1) < 0)
       +                                ;
                        }
                }
        }
       -struct word nullpath={ "", 0};
       -void doredir(redir *rp)
       +struct word nullpath = { "", 0};
       +
       +void
       +doredir(redir *rp)
        {
                if(rp){
                        doredir(rp->next);
       t@@ -92,22 +86,32 @@ void doredir(redir *rp)
                                        close(rp->from);
                                }
                                break;
       -                case RDUP: Dup(rp->from, rp->to); break;
       -                case RCLOSE: close(rp->from); break;
       +                case RDUP:
       +                        Dup(rp->from, rp->to);
       +                        break;
       +                case RCLOSE:
       +                        close(rp->from);
       +                        break;
                        }
                }
        }
       -word *searchpath(char *w){
       +
       +word*
       +searchpath(char *w)
       +{
                word *path;
                if(strncmp(w, "/", 1)==0
        /*        || strncmp(w, "#", 1)==0 */
                || strncmp(w, "./", 2)==0
                || strncmp(w, "../", 3)==0
       -        || (path=vlook("path")->val)==0)
       +        || (path = vlook("path")->val)==0)
                        path=&nullpath;
                return path;
        }
       -void execexec(void){
       +
       +void
       +execexec(void)
       +{
                popword();        /* "exec" */
                if(runq->argv->words==0){
                        Xerror1("empty argument list");
       t@@ -117,19 +121,24 @@ void execexec(void){
                Execute(runq->argv->words, searchpath(runq->argv->words->word));
                poplist();
        }
       -void execfunc(var *func)
       +
       +void
       +execfunc(var *func)
        {
                word *starval;
                popword();
       -        starval=runq->argv->words;
       -        runq->argv->words=0;
       +        starval = runq->argv->words;
       +        runq->argv->words = 0;
                poplist();
                start(func->fn, func->pc, (struct var *)0);
       -        runq->local=newvar(strdup("*"), runq->local);
       -        runq->local->val=starval;
       -        runq->local->changed=1;
       +        runq->local = newvar(strdup("*"), runq->local);
       +        runq->local->val = starval;
       +        runq->local->changed = 1;
        }
       -int dochdir(char *word){
       +
       +int
       +dochdir(char *word)
       +{
                /* report to /dev/wdir if it exists and we're interactive */
                static int wdirfd = -2;
                if(chdir(word)<0) return -1;
       t@@ -141,21 +150,26 @@ int dochdir(char *word){
                }
                return 1;
        }
       -void execcd(void){
       -        word *a=runq->argv->words;
       +
       +void
       +execcd(void)
       +{
       +        word *a = runq->argv->words;
                word *cdpath;
                char dir[512];
                setstatus("can't cd");
       -        cdpath=vlook("cdpath")->val;
       +        cdpath = vlook("cdpath")->val;
                switch(count(a)){
                default:
                        pfmt(err, "Usage: cd [directory]\n");
                        break;
                case 2:
       -                if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath;
       -                for(;cdpath;cdpath=cdpath->next){
       +                if(a->next->word[0]=='/' || cdpath==0)
       +                        cdpath=&nullpath;
       +                for(;cdpath;cdpath = cdpath->next){
                                strcpy(dir, cdpath->word);
       -                        if(dir[0]) strcat(dir, "/");
       +                        if(dir[0])
       +                                strcat(dir, "/");
                                strcat(dir, a->next->word);
                                if(dochdir(dir)>=0){
                                        if(strlen(cdpath->word)
       t@@ -165,10 +179,11 @@ void execcd(void){
                                        break;
                                }
                        }
       -                if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word);
       +                if(cdpath==0)
       +                        pfmt(err, "Can't cd %s: %r\n", a->next->word);
                        break;
                case 1:
       -                a=vlook("HOME")->val;
       +                a = vlook("home")->val;
                        if(count(a)>=1){
                                if(dochdir(a->word)>=0)
                                        setstatus("");
       t@@ -181,14 +196,22 @@ void execcd(void){
                }
                poplist();
        }
       -void execexit(void){
       +
       +void
       +execexit(void)
       +{
                switch(count(runq->argv->words)){
       -        default: pfmt(err, "Usage: exit [status]\nExiting anyway\n");
       -        case 2: setstatus(runq->argv->words->next->word);
       +        default:
       +                pfmt(err, "Usage: exit [status]\nExiting anyway\n");
       +        case 2:
       +                setstatus(runq->argv->words->next->word);
                case 1:        Xexit();
                }
        }
       -void execshift(void){
       +
       +void
       +execshift(void)
       +{
                int n;
                word *a;
                var *star;
       t@@ -198,72 +221,87 @@ void execshift(void){
                        setstatus("shift usage");
                        poplist();
                        return;
       -        case 2: n=atoi(runq->argv->words->next->word); break;
       -        case 1: n=1; break;
       +        case 2:
       +                n = atoi(runq->argv->words->next->word);
       +                break;
       +        case 1:
       +                n = 1;
       +                break;
                }
       -        star=vlook("*");
       +        star = vlook("*");
                for(;n && star->val;--n){
       -                a=star->val->next;
       +                a = star->val->next;
                        efree(star->val->word);
                        efree((char *)star->val);
       -                star->val=a;
       -                star->changed=1;
       +                star->val = a;
       +                star->changed = 1;
                }
                setstatus("");
                poplist();
        }
       -int octal(char *s)
       +
       +int
       +octal(char *s)
        {
       -        int n=0;
       +        int n = 0;
                while(*s==' ' || *s=='\t' || *s=='\n') s++;
       -        while('0'<=*s && *s<='7') n=n*8+*s++-'0';
       +        while('0'<=*s && *s<='7') n = n*8+*s++-'0';
                return n;
        }
       -int mapfd(int fd)
       +
       +int
       +mapfd(int fd)
        {
                redir *rp;
       -        for(rp=runq->redir;rp;rp=rp->next){
       +        for(rp = runq->redir;rp;rp = rp->next){
                        switch(rp->type){
                        case RCLOSE:
       -                        if(rp->from==fd) fd=-1;
       +                        if(rp->from==fd)
       +                                fd=-1;
                                break;
                        case RDUP:
                        case ROPEN:
       -                        if(rp->to==fd) fd=rp->from;
       +                        if(rp->to==fd)
       +                                fd = rp->from;
                                break;
                        }
                }
                return fd;
        }
        union code rdcmds[4];
       -void execcmds(io *f)
       +
       +void
       +execcmds(io *f)
        {
       -        static int first=1;
       +        static int first = 1;
                if(first){
       -                rdcmds[0].i=1;
       -                rdcmds[1].f=Xrdcmds;
       -                rdcmds[2].f=Xreturn;
       -                first=0;
       +                rdcmds[0].i = 1;
       +                rdcmds[1].f = Xrdcmds;
       +                rdcmds[2].f = Xreturn;
       +                first = 0;
                }
                start(rdcmds, 1, runq->local);
       -        runq->cmdfd=f;
       -        runq->iflast=0;
       +        runq->cmdfd = f;
       +        runq->iflast = 0;
        }
       -void execeval(void){
       +
       +void
       +execeval(void)
       +{
                char *cmdline, *s, *t;
       -        int len=0;
       +        int len = 0;
                word *ap;
                if(count(runq->argv->words)<=1){
                        Xerror1("Usage: eval cmd ...");
                        return;
                }
       -        eflagok=1;
       -        for(ap=runq->argv->words->next;ap;ap=ap->next)
       +        eflagok = 1;
       +        for(ap = runq->argv->words->next;ap;ap = ap->next)
                        len+=1+strlen(ap->word);
       -        cmdline=emalloc(len);
       -        s=cmdline;
       -        for(ap=runq->argv->words->next;ap;ap=ap->next){
       -                for(t=ap->word;*t;) *s++=*t++;
       +        cmdline = emalloc(len);
       +        s = cmdline;
       +        for(ap = runq->argv->words->next;ap;ap = ap->next){
       +                for(t = ap->word;*t;) *s++=*t++;
                        *s++=' ';
                }
                s[-1]='\n';
       t@@ -272,36 +310,39 @@ void execeval(void){
                efree(cmdline);
        }
        union code dotcmds[14];
       -void execdot(void){
       -        int iflag=0;
       +
       +void
       +execdot(void)
       +{
       +        int iflag = 0;
                int fd;
                list *av;
       -        thread *p=runq;
       +        thread *p = runq;
                char *zero;
       -        static int first=1;
       +        static int first = 1;
                char file[512];
                word *path;
                if(first){
       -                dotcmds[0].i=1;
       -                dotcmds[1].f=Xmark;
       -                dotcmds[2].f=Xword;
       +                dotcmds[0].i = 1;
       +                dotcmds[1].f = Xmark;
       +                dotcmds[2].f = Xword;
                        dotcmds[3].s="0";
       -                dotcmds[4].f=Xlocal;
       -                dotcmds[5].f=Xmark;
       -                dotcmds[6].f=Xword;
       +                dotcmds[4].f = Xlocal;
       +                dotcmds[5].f = Xmark;
       +                dotcmds[6].f = Xword;
                        dotcmds[7].s="*";
       -                dotcmds[8].f=Xlocal;
       -                dotcmds[9].f=Xrdcmds;
       -                dotcmds[10].f=Xunlocal;
       -                dotcmds[11].f=Xunlocal;
       -                dotcmds[12].f=Xreturn;
       -                first=0;
       +                dotcmds[8].f = Xlocal;
       +                dotcmds[9].f = Xrdcmds;
       +                dotcmds[10].f = Xunlocal;
       +                dotcmds[11].f = Xunlocal;
       +                dotcmds[12].f = Xreturn;
       +                first = 0;
                }
                else
       -                eflagok=1;
       +                eflagok = 1;
                popword();
                if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
       -                iflag=1;
       +                iflag = 1;
                        popword();
                }
                /* get input file */
       t@@ -309,18 +350,20 @@ void execdot(void){
                        Xerror1("Usage: . [-i] file [arg ...]");
                        return;
                }
       -        zero=strdup(p->argv->words->word);
       +        zero = strdup(p->argv->words->word);
                popword();
                fd=-1;
       -        for(path=searchpath(zero);path;path=path->next){
       +        for(path = searchpath(zero);path;path = path->next){
                        strcpy(file, path->word);
       -                if(file[0]) strcat(file, "/");
       +                if(file[0])
       +                        strcat(file, "/");
                        strcat(file, zero);
       +                if((fd = open(file, 0))>=0) break;
                        if(strcmp(file, "/dev/stdin")==0){        /* for sun & ucb */
       -                        fd=Dup1(0);
       -                        if(fd>=0) break;
       +                        fd = Dup1(0);
       +                        if(fd>=0)
       +                                break;
                        }
       -                if((fd=open(file, 0))>=0) break;
                }
                if(fd<0){
                        pfmt(err, "%s: ", zero);
       t@@ -331,38 +374,41 @@ void execdot(void){
                /* set up for a new command loop */
                start(dotcmds, 1, (struct var *)0);
                pushredir(RCLOSE, fd, 0);
       -        runq->cmdfile=zero;
       -        runq->cmdfd=openfd(fd);
       -        runq->iflag=iflag;
       -        runq->iflast=0;
       +        runq->cmdfile = zero;
       +        runq->cmdfd = openfd(fd);
       +        runq->iflag = iflag;
       +        runq->iflast = 0;
                /* push $* value */
                pushlist();
       -        runq->argv->words=p->argv->words;
       +        runq->argv->words = p->argv->words;
                /* free caller's copy of $* */
       -        av=p->argv;
       -        p->argv=av->next;
       +        av = p->argv;
       +        p->argv = av->next;
                efree((char *)av);
                /* push $0 value */
                pushlist();
                pushword(zero);
                ndot++;
        }
       -void execflag(void){
       +
       +void
       +execflag(void)
       +{
                char *letter, *val;
                switch(count(runq->argv->words)){
                case 2:
                        setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
                        break;
                case 3:
       -                letter=runq->argv->words->next->word;
       -                val=runq->argv->words->next->next->word;
       +                letter = runq->argv->words->next->word;
       +                val = runq->argv->words->next->next->word;
                        if(strlen(letter)==1){
                                if(strcmp(val, "+")==0){
       -                                flag[(uchar)letter[0]]=flagset;
       +                                flag[(uchar)letter[0]] = flagset;
                                        break;
                                }
                                if(strcmp(val, "-")==0){
       -                                flag[(uchar)letter[0]]=0;
       +                                flag[(uchar)letter[0]] = 0;
                                        break;
                                }
                        }
       t@@ -372,53 +418,57 @@ void execflag(void){
                }
                poplist();
        }
       -void execwhatis(void){        /* mildly wrong -- should fork before writing */
       +
       +void
       +execwhatis(void){        /* mildly wrong -- should fork before writing */
                word *a, *b, *path;
                var *v;
                struct builtin *bp;
                char file[512];
                struct io out[1];
                int found, sep;
       -        a=runq->argv->words->next;
       +        a = runq->argv->words->next;
                if(a==0){
                        Xerror1("Usage: whatis name ...");
                        return;
                }
                setstatus("");
       -        out->fd=mapfd(1);
       -        out->bufp=out->buf;
       -        out->ebuf=&out->buf[NBUF];
       -        out->strp=0;
       -        for(;a;a=a->next){
       -                v=vlook(a->word);
       +        out->fd = mapfd(1);
       +        out->bufp = out->buf;
       +        out->ebuf = &out->buf[NBUF];
       +        out->strp = 0;
       +        for(;a;a = a->next){
       +                v = vlook(a->word);
                        if(v->val){
                                pfmt(out, "%s=", a->word);
                                if(v->val->next==0)
                                        pfmt(out, "%q\n", v->val->word);
                                else{
                                        sep='(';
       -                                for(b=v->val;b && b->word;b=b->next){
       +                                for(b = v->val;b && b->word;b = b->next){
                                                pfmt(out, "%c%q", sep, b->word);
                                                sep=' ';
                                        }
                                        pfmt(out, ")\n");
                                }
       -                        found=1;
       +                        found = 1;
                        }
                        else
       -                        found=0;
       -                v=gvlook(a->word);
       -                if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
       +                        found = 0;
       +                v = gvlook(a->word);
       +                if(v->fn)
       +                        pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
                        else{
       -                        for(bp=Builtin;bp->name;bp++)
       +                        for(bp = Builtin;bp->name;bp++)
                                        if(strcmp(a->word, bp->name)==0){
                                                pfmt(out, "builtin %s\n", a->word);
                                                break;
                                        }
                                if(!bp->name){
       -                                for(path=searchpath(a->word);path;path=path->next){
       +                                for(path = searchpath(a->word);path;path = path->next){
                                                strcpy(file, path->word);
       -                                        if(file[0]) strcat(file, "/");
       +                                        if(file[0])
       +                                                strcat(file, "/");
                                                strcat(file, a->word);
                                                if(Executable(file)){
                                                        pfmt(out, "%s\n", file);
       t@@ -435,11 +485,20 @@ void execwhatis(void){        /* mildly wrong -- should fork before writing */
                poplist();
                flush(err);
        }
       -void execwait(void){
       +
       +void
       +execwait(void)
       +{
                switch(count(runq->argv->words)){
       -        default: Xerror1("Usage: wait [pid]"); return;
       -        case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break;
       -        case 1: Waitfor(-1, 0); break;
       +        default:
       +                Xerror1("Usage: wait [pid]");
       +                return;
       +        case 2:
       +                Waitfor(atoi(runq->argv->words->next->word), 0);
       +                break;
       +        case 1:
       +                Waitfor(-1, 0);
       +                break;
                }
                poplist();
        }
 (DIR) diff --git a/src/cmd/rc/subr.c b/src/cmd/rc/subr.c
       t@@ -2,20 +2,29 @@
        #include "exec.h"
        #include "io.h"
        #include "fns.h"
       -char *emalloc(long n){
       -        char *p=(char *)Malloc(n);
       -        if(p==0) panic("Can't malloc %d bytes", n);
       -/*        if(err){ pfmt(err, "malloc %d->%p\n", n, p); flush(err); } */
       +
       +char*
       +emalloc(long n)
       +{
       +        char *p = (char *)Malloc(n);
       +        if(p==0)
       +                panic("Can't malloc %d bytes", n);
       +/*        if(err){ pfmt(err, "malloc %d->%p\n", n, p); flush(err); } /**/
                return p;
        }
       -void efree(char *p)
       +
       +void
       +efree(char *p)
        {
       -/*        pfmt(err, "free %p\n", p); flush(err); */
       -        if(p) free(p);
       +/*        pfmt(err, "free %p\n", p); flush(err); /**/
       +        if(p)
       +                free(p);
                else pfmt(err, "free 0\n");
        }
        extern int lastword, lastdol;
       -void yyerror(char *m)
       +
       +void
       +yyerror(char *m)
        {
                pfmt(err, "rc: ");
                if(runq->cmdfile && !runq->iflag)
       t@@ -24,17 +33,21 @@ void yyerror(char *m)
                        pfmt(err, "%s: ", runq->cmdfile);
                else if(!runq->iflag)
                        pfmt(err, "line %d: ", runq->lineno);
       -        if(tok[0] && tok[0]!='\n') pfmt(err, "token %q: ", tok);
       +        if(tok[0] && tok[0]!='\n')
       +                pfmt(err, "token %q: ", tok);
                pfmt(err, "%s\n", m);
                flush(err);
       -        lastword=0;
       -        lastdol=0;
       +        lastword = 0;
       +        lastdol = 0;
                while(lastc!='\n' && lastc!=EOF) advance();
                nerror++;
                setvar("status", newword(m, (word *)0));
        }
        char *bp;
       -void iacvt(int n){
       +
       +static void
       +iacvt(int n)
       +{
                if(n<0){
                        *bp++='-';
                        n=-n;        /* doesn't work for n==-inf */
       t@@ -43,13 +56,17 @@ void iacvt(int n){
                        iacvt(n/10);
                *bp++=n%10+'0';
        }
       -void itoa(char *s, long n)
       +
       +void
       +inttoascii(char *s, long n)
        {
       -        bp=s;
       +        bp = s;
                iacvt(n);
                *bp='\0';
        }
       -void panic(char *s, int n)
       +
       +void
       +panic(char *s, int n)
        {
                pfmt(err, "rc: ");
                pfmt(err, s, n);
 (DIR) diff --git a/src/cmd/rc/syn.y b/src/cmd/rc/syn.y
       t@@ -2,7 +2,6 @@
        %term WORD REDIR DUP PIPE SUB
        %term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
        /* operator priorities -- lowest first */
       -%left LOW
        %left IF WHILE FOR SWITCH ')' NOT
        %left ANDAND OROR
        %left BANG SUBSHELL
       t@@ -10,7 +9,6 @@
        %left '^'
        %right '$' COUNT '"'
        %left SUB
       -%left '='
        %{
        #include "rc.h"
        #include "fns.h"
       t@@ -80,7 +78,6 @@ first:        comword
        word:        keyword                        {lastword=1; $1->type=WORD;}
        |        comword
        |        word '^' word                {$$=tree2('^', $1, $3);}
       -|        word '=' word %prec LOW                {$$=tree2('^', tree2('^', $1, token("=", WORD)), $3);}
        comword: '$' word                {$$=tree1('$', $2);}
        |        '$' word SUB words ')'        {$$=tree2(SUB, $2, $4);}
        |        '"' word                {$$=tree1('"', $2);}
 (DIR) diff --git a/src/cmd/rc/trap.c b/src/cmd/rc/trap.c
       t@@ -3,22 +3,25 @@
        #include "fns.h"
        #include "io.h"
        extern char *Signame[];
       -void dotrap(void){
       -        register int i;
       -        register struct var *trapreq;
       -        register struct word *starval;
       -        starval=vlook("*")->val;
       -        while(ntrap) for(i=0;i!=NSIG;i++) while(trap[i]){
       +
       +void
       +dotrap(void)
       +{
       +        int i;
       +        struct var *trapreq;
       +        struct word *starval;
       +        starval = vlook("*")->val;
       +        while(ntrap) for(i = 0;i!=NSIG;i++) while(trap[i]){
                        --trap[i];
                        --ntrap;
                        if(getpid()!=mypid) Exit(getstatus());
       -                trapreq=vlook(Signame[i]);
       +                trapreq = vlook(Signame[i]);
                        if(trapreq->fn){
                                start(trapreq->fn, trapreq->pc, (struct var *)0);
       -                        runq->local=newvar(strdup("*"), runq->local);
       -                        runq->local->val=copywords(starval, (struct word *)0);
       -                        runq->local->changed=1;
       -                        runq->redir=runq->startredir=0;
       +                        runq->local = newvar(strdup("*"), runq->local);
       +                        runq->local->val = copywords(starval, (struct word *)0);
       +                        runq->local->changed = 1;
       +                        runq->redir = runq->startredir = 0;
                        }
                        else if(i==SIGINT || i==SIGQUIT){
                                /*
 (DIR) diff --git a/src/cmd/rc/tree.c b/src/cmd/rc/tree.c
       t@@ -7,108 +7,140 @@ tree *treenodes;
         * create and clear a new tree node, and add it
         * to the node list.
         */
       -tree *newtree(void){
       -        tree *t=new(tree);
       -        t->iskw=0;
       -        t->str=0;
       -        t->child[0]=t->child[1]=t->child[2]=0;
       -        t->next=treenodes;
       -        treenodes=t;
       +
       +tree*
       +newtree(void)
       +{
       +        tree *t = new(tree);
       +        t->iskw = 0;
       +        t->str = 0;
       +        t->child[0] = t->child[1] = t->child[2] = 0;
       +        t->next = treenodes;
       +        treenodes = t;
                return t;
        }
       -void freenodes(void){
       +
       +void
       +freenodes(void)
       +{
                tree *t, *u;
       -        for(t=treenodes;t;t=u){
       -                u=t->next;
       -                if(t->str) efree(t->str);
       +        for(t = treenodes;t;t = u){
       +                u = t->next;
       +                if(t->str)
       +                        efree(t->str);
                        efree((char *)t);
                }
       -        treenodes=0;
       +        treenodes = 0;
        }
       -tree *tree1(int type, tree *c0)
       +
       +tree*
       +tree1(int type, tree *c0)
        {
                return tree3(type, c0, (tree *)0, (tree *)0);
        }
       -tree *tree2(int type, tree *c0, tree *c1)
       +
       +tree*
       +tree2(int type, tree *c0, tree *c1)
        {
                return tree3(type, c0, c1, (tree *)0);
        }
       -tree *tree3(int type, tree *c0, tree *c1, tree *c2)
       +
       +tree*
       +tree3(int type, tree *c0, tree *c1, tree *c2)
        {
                tree *t;
                if(type==';'){
       -                if(c0==0) return c1;
       -                if(c1==0) return c0;
       +                if(c0==0)
       +                        return c1;
       +                if(c1==0)
       +                        return c0;
                }
       -        t=newtree();
       -        t->type=type;
       -        t->child[0]=c0;
       -        t->child[1]=c1;
       -        t->child[2]=c2;
       +        t = newtree();
       +        t->type = type;
       +        t->child[0] = c0;
       +        t->child[1] = c1;
       +        t->child[2] = c2;
                return t;
        }
       -tree *mung1(tree *t, tree *c0)
       +
       +tree*
       +mung1(tree *t, tree *c0)
        {
       -        t->child[0]=c0;
       +        t->child[0] = c0;
                return t;
        }
       -tree *mung2(tree *t, tree *c0, tree *c1)
       +
       +tree*
       +mung2(tree *t, tree *c0, tree *c1)
        {
       -        t->child[0]=c0;
       -        t->child[1]=c1;
       +        t->child[0] = c0;
       +        t->child[1] = c1;
                return t;
        }
       -tree *mung3(tree *t, tree *c0, tree *c1, tree *c2)
       +
       +tree*
       +mung3(tree *t, tree *c0, tree *c1, tree *c2)
        {
       -        t->child[0]=c0;
       -        t->child[1]=c1;
       -        t->child[2]=c2;
       +        t->child[0] = c0;
       +        t->child[1] = c1;
       +        t->child[2] = c2;
                return t;
        }
       -tree *epimung(tree *comp, tree *epi)
       +
       +tree*
       +epimung(tree *comp, tree *epi)
        {
                tree *p;
       -        if(epi==0) return comp;
       -        for(p=epi;p->child[1];p=p->child[1]);
       -        p->child[1]=comp;
       +        if(epi==0)
       +                return comp;
       +        for(p = epi;p->child[1];p = p->child[1]);
       +        p->child[1] = comp;
                return epi;
        }
        /*
         * Add a SIMPLE node at the root of t and percolate all the redirections
         * up to the root.
         */
       -tree *simplemung(tree *t)
       +
       +tree*
       +simplemung(tree *t)
        {
                tree *u;
                struct io *s;
       -        t=tree1(SIMPLE, t);
       -        s=openstr();
       +        t = tree1(SIMPLE, t);
       +        s = openstr();
                pfmt(s, "%t", t);
       -        t->str=strdup(s->strp);
       +        t->str = strdup(s->strp);
                closeio(s);
       -        for(u=t->child[0];u->type==ARGLIST;u=u->child[0]){
       +        for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){
                        if(u->child[1]->type==DUP
                        || u->child[1]->type==REDIR){
       -                        u->child[1]->child[1]=t;
       -                        t=u->child[1];
       -                        u->child[1]=0;
       +                        u->child[1]->child[1] = t;
       +                        t = u->child[1];
       +                        u->child[1] = 0;
                        }
                }
                return t;
        }
       -tree *token(char *str, int type)
       +
       +tree*
       +token(char *str, int type)
        {
       -        tree *t=newtree();
       -        t->type=type;
       -        t->str=strdup(str);
       +        tree *t = newtree();
       +        t->type = type;
       +        t->str = strdup(str);
                return t;
        }
       -void freetree(tree *p)
       +
       +void
       +freetree(tree *p)
        {
       -        if(p==0) return;        
       +        if(p==0)
       +                return;        
                freetree(p->child[0]);
                freetree(p->child[1]);
                freetree(p->child[2]);
       -        if(p->str) efree(p->str);
       +        if(p->str)
       +                efree(p->str);
                efree((char *)p);
        }
 (DIR) diff --git a/src/cmd/rc/var.c b/src/cmd/rc/var.c
       t@@ -1,9 +1,11 @@
        #include "rc.h"
        #include "exec.h"
        #include "fns.h"
       -int hash(char *s, int n)
       +
       +int
       +hash(char *s, int n)
        {
       -        register int h=0, i=1;
       +        int h = 0, i = 1;
                while(*s) h+=*s++*i++;
                h%=n;
                return h<0?h+n:h;
       t@@ -14,16 +16,21 @@ struct kw{
                int type;
                struct kw *next;
        }*kw[NKW];
       -void kenter(int type, char *name)
       +
       +void
       +kenter(int type, char *name)
        {
       -        register int h=hash(name, NKW);
       -        register struct kw *p=new(struct kw);
       -        p->type=type;
       -        p->name=name;
       -        p->next=kw[h];
       -        kw[h]=p;
       +        int h = hash(name, NKW);
       +        struct kw *p = new(struct kw);
       +        p->type = type;
       +        p->name = name;
       +        p->next = kw[h];
       +        kw[h] = p;
        }
       -void kinit(void){
       +
       +void
       +kinit(void)
       +{
                kenter(FOR, "for");
                kenter(IN, "in");
                kenter(WHILE, "while");
       t@@ -35,47 +42,59 @@ void kinit(void){
                kenter(SWITCH, "switch");
                kenter(FN, "fn");
        }
       -tree *klook(char *name)
       +
       +tree*
       +klook(char *name)
        {
                struct kw *p;
       -        tree *t=token(name, WORD);
       -        for(p=kw[hash(name, NKW)];p;p=p->next)
       +        tree *t = token(name, WORD);
       +        for(p = kw[hash(name, NKW)];p;p = p->next)
                        if(strcmp(p->name, name)==0){
       -                        t->type=p->type;
       -                        t->iskw=1;
       +                        t->type = p->type;
       +                        t->iskw = 1;
                                break;
                        }
                return t;
        }
       -var *gvlook(char *name)
       +
       +var*
       +gvlook(char *name)
        {
       -        int h=hash(name, NVAR);
       +        int h = hash(name, NVAR);
                var *v;
       -        for(v=gvar[h];v;v=v->next) if(strcmp(v->name, name)==0) return v;
       -        return gvar[h]=newvar(strdup(name), gvar[h]);
       +        for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return v;
       +        return gvar[h] = newvar(strdup(name), gvar[h]);
        }
       -var *vlook(char *name)
       +
       +var*
       +vlook(char *name)
        {
                var *v;
                if(runq)
       -                for(v=runq->local;v;v=v->next)
       +                for(v = runq->local;v;v = v->next)
                                if(strcmp(v->name, name)==0) return v;
                return gvlook(name);
        }
       -void _setvar(char *name, word *val, int callfn)
       +
       +void
       +_setvar(char *name, word *val, int callfn)
        {
       -        register struct var *v=vlook(name);
       +        struct var *v = vlook(name);
                freewords(v->val);
                v->val=val;
                v->changed=1;
                if(callfn && v->changefn)
                        v->changefn(v);
        }
       -void setvar(char *name, word *val)
       +
       +void
       +setvar(char *name, word *val)
        {
                _setvar(name, val, 1);
        }
       -void bigpath(var *v)
       +
       +void
       +bigpath(var *v)
        {
                /* convert $PATH to $path */
                char *p, *q;
       t@@ -107,19 +126,42 @@ void bigpath(var *v)
                }
                _setvar("path", w, 0);
        }
       -void littlepath(var *v)
       +
       +char*
       +list2strcolon(word *words)
       +{
       +        char *value, *s, *t;
       +        int len = 0;
       +        word *ap;
       +        for(ap = words;ap;ap = ap->next)
       +                len+=1+strlen(ap->word);
       +        value = emalloc(len+1);
       +        s = value;
       +        for(ap = words;ap;ap = ap->next){
       +                for(t = ap->word;*t;) *s++=*t++;
       +                *s++=':';
       +        }
       +        if(s==value)
       +                *s='\0';
       +        else s[-1]='\0';
       +        return value;
       +}
       +void
       +littlepath(var *v)
        {
                /* convert $path to $PATH */
                char *p;
                word *w;
        
       -        p = _list2str(v->val, ':');
       +        p = list2strcolon(v->val);
                w = new(word);
                w->word = p;
                w->next = nil;
                _setvar("PATH", w, 1);        /* 1: recompute $path to expose colon problems */
        }
       -void pathinit(void)
       +
       +void
       +pathinit(void)
        {
                var *v;