commit c8f538425f4e92e1e438b9bd25cb08e250a93d5b from: rsc date: Mon Mar 26 12:02:41 2007 UTC sync with plan 9 commit - 79049567a0fac8707ea3f2927403445bdb2394fa commit + c8f538425f4e92e1e438b9bd25cb08e250a93d5b blob - 748b9f8246ac5df0ebda29915ad3bfdabb00c667 blob + 0ae90eebf4a053bc1b7e189553757e3cd238b4fd --- src/cmd/rc/code.c +++ src/cmd/rc/code.c @@ -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); @@ -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){ @@ -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); @@ -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); @@ -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; @@ -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 $* */ @@ -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; @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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: @@ -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 */ @@ -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); @@ -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++; blob - 72e5784580af5125cc6eef2f27fd978ba1d3789f blob + 86d97cd258d50c0b19851e923c203d8ae0cd13f8 --- src/cmd/rc/exec.c +++ src/cmd/rc/exec.c @@ -1,9 +1,3 @@ -#include -#include -#if defined(PLAN9PORT) && defined(__sun__) -# define BSD_COMP /* sigh. for TIOCNOTTY */ -#endif -#include #include "rc.h" #include "getflags.h" #include "exec.h" @@ -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) + +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; + 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* +newword(char *wd, word *next) { - word *p=new(word); - p->word=strdup(wd); - p->next=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; + +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* +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; + var *v = new(var); + v->name = name; + v->val = 0; + v->fn = 0; + v->changed = 0; + v->fnchanged = 0; + v->next = next; return v; } /* @@ -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(); } } /* @@ -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 @@ -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; @@ -226,127 +261,115 @@ void Xappend(void){ pushredir(ROPEN, f, runq->code[runq->pc].i); 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; @@ -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; @@ -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; + 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'; + 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; @@ -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; } } @@ -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"); @@ -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; @@ -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; @@ -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); } @@ -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 || lennext; + n = 0; + while('0'<=*s && *s<='9') n = n*10+ *s++ -'0'; + if(n<1 || lennext; 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; @@ -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; + 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; + 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(npid==-1) setstatus(concstatus(runq->status, getstatus())); @@ -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 */ } @@ -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); @@ -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); @@ -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(); } blob - 1704b6f322f974b3dd60f0ef213b42d6a9661d25 blob + 06d2991f55d4cd25768d91598b825c905cd60398 --- src/cmd/rc/exec.h +++ src/cmd/rc/exec.h @@ -5,6 +5,7 @@ extern void Xappend(void), Xasync(void), Xbackq(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); @@ -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 */ @@ -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 *); blob - b9e5cb73698c47d53ec67dcb512a2e7f65dec366 blob + f6454787f278e661eeea049ad9f583cbfd7ec07b --- src/cmd/rc/fns.h +++ src/cmd/rc/fns.h @@ -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*); @@ -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); @@ -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); @@ -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); blob - c452067fd511aead421cdf50ea254dff05bad8ae blob + 09f6e3a71e0710aeff4a4b75013ae818ae21d270 --- src/cmd/rc/getflags.c +++ src/cmd/rc/getflags.c @@ -3,7 +3,7 @@ #include "rc.h" #include "getflags.h" #include "fns.h" -char *flagset[]={""}; +char *flagset[] = {""}; char **flag[NFLAG]; char cmdline[NCMDLINE+1]; char *cmdname; @@ -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-inext) 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); } } @@ -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); @@ -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; @@ -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; @@ -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); @@ -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(hinext); 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; } } blob - 6e4aa92444ec7ac768a70b1e8619770cc86a9546 blob + e81046d619af2a1a121e2d43c44a659860b46174 --- src/cmd/rc/havefork.c +++ src/cmd/rc/havefork.c @@ -1,5 +1,3 @@ -#include -#include #include "rc.h" #include "getflags.h" #include "exec.h" @@ -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; @@ -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; blob - 2a0fe2f2024d130019981aeeed1a850145ad914a blob + 17c62458139deadb68d54dccbf14c3db387e3853 --- src/cmd/rc/here.c +++ src/cmd/rc/here.c @@ -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); } /* @@ -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); @@ -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; @@ -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); } blob - /dev/null blob + 29e2272bb5eed053eefbcb88e55c236d1d6729c9 (mode 644) --- /dev/null +++ src/cmd/rc/havep9p.c @@ -0,0 +1,246 @@ +#include +#include +#if defined(PLAN9PORT) && defined(__sun__) +# define BSD_COMP /* sigh. for TIOCNOTTY */ +#endif +#include +#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; +} blob - c360b4a082aa5ade452b676943337422488a0167 blob + 3ad1e2db3bc033068743cd27dafc9e63af2366ee --- src/cmd/rc/io.c +++ src/cmd/rc/io.c @@ -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; @@ -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; } blob - ec511871fa6e21a2cefff88a4c3e1cccfb169fae blob + 21cc6b8e8fdfc44b5c7f0727fc09ea74868eeb61 --- src/cmd/rc/io.h +++ src/cmd/rc/io.h @@ -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*); blob - b0e27eb353845942776c7e132927c3db81d2a0c4 blob + 3693483281217cecbe7e87e8941da70081cfa0fc --- src/cmd/rc/lex.c +++ src/cmd/rc/lex.c @@ -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: @@ -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 @@ -146,7 +193,7 @@ int yylex(void){ * we insert a `^' before it. */ if(lastword){ - lastword=0; + lastword = 0; if(d=='('){ advance(); strcpy(tok, "( [SUB]"); @@ -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; @@ -177,7 +224,7 @@ int yylex(void){ strcpy(tok, "$"); return '$'; case '&': - lastdol=0; + lastdol = 0; if(nextis('&')){ skipnl(); strcpy(tok, "&&"); @@ -186,7 +233,7 @@ int yylex(void){ strcpy(tok, "&"); return '&'; case '|': - lastdol=0; + lastdol = 0; if(nextis(c)){ skipnl(); strcpy(tok, "||"); @@ -194,7 +241,7 @@ int yylex(void){ } case '<': case '>': - lastdol=0; + lastdol = 0; /* * funny redirection tokens: * redir: arrow | arrow '[' fd ']' @@ -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'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; } - blob - b3d8ffd00e9b3583d3134fd23b0a8c0fafde2726 blob + d1144e8584acc60cd8fee5fb043154a762aee9b6 --- src/cmd/rc/mkfile +++ src/cmd/rc/mkfile @@ -20,6 +20,7 @@ OFILES=\ var.$O\ y.tab.$O\ plan9ish.$O\ + havep9p.$O\ HFILES=\ rc.h\ blob - 0f84298ae3784d45484c059bd41f4244b00c881b blob + 8caf60a28cc0a0ff2babe23be79919f0942304c1 --- src/cmd/rc/pcmd.c +++ src/cmd/rc/pcmd.c @@ -5,39 +5,66 @@ char nl='\n'; /* change to semicolon for bourne-proof #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); @@ -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: @@ -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); blob - a4606e7c5830f6a36dbb5a05d808c8946db83bf2 blob + 3f2b4c98a3477693c0bb40ad1ab8313c94753c4f --- src/cmd/rc/pfnc.c +++ src/cmd/rc/pfnc.c @@ -5,7 +5,7 @@ struct{ void (*f)(void); char *name; -}fname[]={ +}fname[] = { Xappend, "Xappend", Xasync, "Xasync", Xbang, "Xbang", @@ -18,6 +18,7 @@ struct{ Xjump, "Xjump", Xmark, "Xmark", Xpopm, "Xpopm", + Xrdwr, "Xrdwr", Xread, "Xread", Xreturn, "Xreturn", Xtrue, "Xtrue", @@ -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); } blob - 4e1ab7c055ff67639d043b39e538f128ccfec80a blob + 1e8965361ba393d4cf0ea90ba5a283db29e2a46d --- src/cmd/rc/plan9ish.c +++ src/cmd/rc/plan9ish.c @@ -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 */ blob - 3e79617d55843ff617bb229c680233f0c7d9999e blob + f95b52875e48cf756548f9a5af2b9ec9152c6c5d --- src/cmd/rc/rc.h +++ src/cmd/rc/rc.h @@ -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 */ blob - 154678f64c99860c3d9313cde809403363b5ff22 blob + 15814c5c934c571e66a738e9a96d41fb3b342067 --- src/cmd/rc/simple.c +++ src/cmd/rc/simple.c @@ -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{ @@ -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; @@ -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); @@ -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"); @@ -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; @@ -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) @@ -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(""); @@ -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; @@ -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'; @@ -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 */ @@ -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); @@ -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; } } @@ -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); @@ -435,11 +485,20 @@ void execwhatis(void){ /* mildly wrong -- should fork 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(); } blob - 06a22b26af535711f549939eff8b779dc6955249 blob + a6b533b36693f01df01ecde969d1c9724de1c990 --- src/cmd/rc/subr.c +++ src/cmd/rc/subr.c @@ -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) @@ -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 */ @@ -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); blob - 5123ce4a33aa43ed0af86569b4018237453866b5 blob + c7de3531385d2618b2a080252c850c3f21633e4e --- src/cmd/rc/syn.y +++ src/cmd/rc/syn.y @@ -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 @@ -10,7 +9,6 @@ %left '^' %right '$' COUNT '"' %left SUB -%left '=' %{ #include "rc.h" #include "fns.h" @@ -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);} blob - 96ef364a6785c4ac125aa36de4f184f72af6e366 blob + a572cac3707665304b9587b48679410049cdc35f --- src/cmd/rc/trap.c +++ src/cmd/rc/trap.c @@ -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){ /* blob - 9bf76d8efb1b7956e88b9c9d9219aaf55ebaeaf4 blob + 897597e286bfb90b6c03c128e14d044cb5732d63 --- src/cmd/rc/tree.c +++ src/cmd/rc/tree.c @@ -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); } blob - 8a200ffd4d705c3e30573d166bbe165c1d8f4745 blob + 2564ba2f756ff944739b36de0b82d629966fc71b --- src/cmd/rc/var.c +++ src/cmd/rc/var.c @@ -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; @@ -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"); @@ -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; @@ -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;