diff options
author | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
commit | c8f538425f4e92e1e438b9bd25cb08e250a93d5b (patch) | |
tree | d701abbcd4973d5b6909d104eefe521de70a4e1c /src/cmd/rc/exec.c | |
parent | 79049567a0fac8707ea3f2927403445bdb2394fa (diff) | |
download | plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.gz plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.bz2 plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.zip |
sync with plan 9
Diffstat (limited to 'src/cmd/rc/exec.c')
-rw-r--r-- | src/cmd/rc/exec.c | 989 |
1 files changed, 504 insertions, 485 deletions
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c index 72e57845..86d97cd2 100644 --- a/src/cmd/rc/exec.c +++ b/src/cmd/rc/exec.c @@ -1,9 +1,3 @@ -#include <u.h> -#include <signal.h> -#if defined(PLAN9PORT) && defined(__sun__) -# define BSD_COMP /* sigh. for TIOCNOTTY */ -#endif -#include <sys/ioctl.h> #include "rc.h" #include "getflags.h" #include "exec.h" @@ -13,91 +7,118 @@ * Start executing the given code at the given pc with the given redirection */ char *argv0="rc"; -void start(code *c, int pc, var *local) -{ - struct thread *p=new(struct thread); - p->code=codecopy(c); - p->pc=pc; - p->argv=0; - p->redir=p->startredir=runq?runq->redir:0; - p->local=local; - p->cmdfile=0; - p->cmdfd=0; - p->eof=0; - p->iflag=0; - p->lineno=1; - p->pid=-1; - p->ret=runq; - runq=p; -} -word *newword(char *wd, word *next) -{ - word *p=new(word); - p->word=strdup(wd); - p->next=next; + +void +start(code *c, int pc, var *local) +{ + struct thread *p = new(struct thread); + + p->code = codecopy(c); + p->pc = pc; + p->argv = 0; + p->redir = p->startredir = runq?runq->redir:0; + p->local = local; + p->cmdfile = 0; + p->cmdfd = 0; + p->eof = 0; + p->iflag = 0; + p->lineno = 1; + p->ret = runq; + runq = p; +} + +word* +newword(char *wd, word *next) +{ + word *p = new(word); + p->word = strdup(wd); + p->next = next; return p; } -void pushword(char *wd) + +void +pushword(char *wd) { - if(runq->argv==0) panic("pushword but no argv!", 0); - runq->argv->words=newword(wd, runq->argv->words); + if(runq->argv==0) + panic("pushword but no argv!", 0); + runq->argv->words = newword(wd, runq->argv->words); } -void popword(void){ + +void +popword(void) +{ word *p; - if(runq->argv==0) panic("popword but no argv!", 0); - p=runq->argv->words; - if(p==0) panic("popword but no word!", 0); - runq->argv->words=p->next; + if(runq->argv==0) + panic("popword but no argv!", 0); + p = runq->argv->words; + if(p==0) + panic("popword but no word!", 0); + runq->argv->words = p->next; efree(p->word); efree((char *)p); } -void freelist(word *w) + +void +freelist(word *w) { word *nw; while(w){ - nw=w->next; + nw = w->next; efree(w->word); efree((char *)w); - w=nw; + w = nw; } } -void pushlist(void){ - list *p=new(list); - p->next=runq->argv; - p->words=0; - runq->argv=p; + +void +pushlist(void) +{ + list *p = new(list); + p->next = runq->argv; + p->words = 0; + runq->argv = p; } -void poplist(void){ - list *p=runq->argv; - if(p==0) panic("poplist but no argv", 0); + +void +poplist(void) +{ + list *p = runq->argv; + if(p==0) + panic("poplist but no argv", 0); freelist(p->words); - runq->argv=p->next; + runq->argv = p->next; efree((char *)p); } -int count(word *w) + +int +count(word *w) { int n; - for(n=0;w;n++) w=w->next; + for(n = 0;w;n++) w = w->next; return n; } -void pushredir(int type, int from, int to){ - redir * rp=new(redir); - rp->type=type; - rp->from=from; - rp->to=to; - rp->next=runq->redir; - runq->redir=rp; -} -var *newvar(char *name, var *next) -{ - var *v=new(var); - v->name=name; - v->val=0; - v->fn=0; - v->changed=0; - v->fnchanged=0; - v->next=next; - v->changefn = 0; + +void +pushredir(int type, int from, int to) +{ + redir * rp = new(redir); + rp->type = type; + rp->from = from; + rp->to = to; + rp->next = runq->redir; + runq->redir = rp; +} + +var* +newvar(char *name, var *next) +{ + var *v = new(var); + v->name = name; + v->val = 0; + v->fn = 0; + v->changed = 0; + v->fnchanged = 0; + v->next = next; return v; } /* @@ -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; @@ -227,126 +262,114 @@ void Xappend(void){ runq->pc++; poplist(); } -void Xasync(void){ - int null=open("/dev/null", 0); - int tty; - int pid; - char npid[10]; - if(null<0){ - Xerror("Can't open /dev/null\n"); - return; - } - switch(pid=rfork(RFFDG|RFPROC|RFNOTEG)){ - case -1: - close(null); - Xerror("try again"); - break; - case 0: - /* - * I don't know what the right thing to do here is, - * so this is all experimentally determined. - * If we just dup /dev/null onto 0, then running - * ssh foo & will reopen /dev/tty, try to read a password, - * get a signal, and repeat, in a tight loop, forever. - * Arguably this is a bug in ssh (it behaves the same - * way under bash as under rc) but I'm fixing it here - * anyway. If we dissociate the process from the tty, - * then it won't be able to open /dev/tty ever again. - * The SIG_IGN on SIGTTOU makes writing the tty - * (via fd 1 or 2, for example) succeed even though - * our pgrp is not the terminal's controlling pgrp. - */ - if((tty=open("/dev/tty", OREAD)) >= 0){ - /* - * Should make reads of tty fail, writes succeed. - */ - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - ioctl(tty, TIOCNOTTY); - close(tty); - } - if(isatty(0)) - pushredir(ROPEN, null, 0); - else - close(null); - start(runq->code, runq->pc+1, runq->local); - runq->ret=0; - break; - default: - close(null); - runq->pc=runq->code[runq->pc].i; - itoa(npid, pid); - setvar("apid", newword(npid, (word *)0)); - break; - } -} -void Xsettrue(void){ + +void +Xsettrue(void) +{ setstatus(""); } -void Xbang(void){ + +void +Xbang(void) +{ setstatus(truestatus()?"false":""); } -void Xclose(void){ + +void +Xclose(void) +{ pushredir(RCLOSE, runq->code[runq->pc].i, 0); runq->pc++; } -void Xdup(void){ + +void +Xdup(void) +{ pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i); runq->pc+=2; } -void Xeflag(void){ + +void +Xeflag(void) +{ if(eflagok && !truestatus()) Xexit(); } -void Xexit(void){ + +void +Xexit(void) +{ struct var *trapreq; struct word *starval; - static int beenhere=0; + static int beenhere = 0; if(getpid()==mypid && !beenhere){ - trapreq=vlook("sigexit"); + trapreq = vlook("sigexit"); if(trapreq->fn){ - beenhere=1; + beenhere = 1; --runq->pc; - starval=vlook("*")->val; + starval = vlook("*")->val; start(trapreq->fn, trapreq->pc, (struct var *)0); - runq->local=newvar(strdup("*"), runq->local); - runq->local->val=copywords(starval, (struct word *)0); - runq->local->changed=1; - runq->redir=runq->startredir=0; + runq->local = newvar(strdup("*"), runq->local); + runq->local->val = copywords(starval, (struct word *)0); + runq->local->changed = 1; + runq->redir = runq->startredir = 0; return; } } Exit(getstatus()); } -void Xfalse(void){ - if(truestatus()) runq->pc=runq->code[runq->pc].i; + +void +Xfalse(void) +{ + if(truestatus()) runq->pc = runq->code[runq->pc].i; else runq->pc++; } int ifnot; /* dynamic if not flag */ -void Xifnot(void){ + +void +Xifnot(void) +{ if(ifnot) runq->pc++; else - runq->pc=runq->code[runq->pc].i; + runq->pc = runq->code[runq->pc].i; } -void Xjump(void){ - runq->pc=runq->code[runq->pc].i; + +void +Xjump(void) +{ + runq->pc = runq->code[runq->pc].i; } -void Xmark(void){ + +void +Xmark(void) +{ pushlist(); } -void Xpopm(void){ + +void +Xpopm(void) +{ poplist(); } -void Xread(void){ + +void +Xread(void) +{ char *file; int f; switch(count(runq->argv->words)){ - default: Xerror1("< requires singleton\n"); return; - case 0: Xerror1("< requires file\n"); return; - case 1: break; + default: + Xerror1("< requires singleton\n"); + return; + case 0: + Xerror1("< requires file\n"); + return; + case 1: + break; } - file=runq->argv->words->word; - if((f=open(file, 0))<0){ + file = runq->argv->words->word; + if((f = open(file, 0))<0){ pfmt(err, "%s: ", file); Xerror("can't open"); return; @@ -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; - } - if(s==value) *s='\0'; + value = emalloc(len+1); + s = value; + for(ap = words;ap;ap = ap->next){ + for(t = ap->word;*t;) *s++=*t++; + *s++=' '; + } + if(s==value) + *s='\0'; else s[-1]='\0'; return value; } -char *list2str(word *words){ - return _list2str(words, ' '); -} -void Xmatch(void){ + +void +Xmatch(void) +{ word *p; char *subject; - subject=list2str(runq->argv->words); + subject = list2str(runq->argv->words); setstatus("no match"); - for(p=runq->argv->next->words;p;p=p->next) + for(p = runq->argv->next->words;p;p = p->next) if(match(subject, p->word, '\0')){ setstatus(""); break; @@ -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 || len<n) return a; - for(;n!=1;--n) val=val->next; + n = 0; + while('0'<=*s && *s<='9') n = n*10+ *s++ -'0'; + if(n<1 || len<n) + return a; + for(;n!=1;--n) val = val->next; return newword(val->word, a); } -void Xsub(void){ + +void +Xsub(void) +{ word *a, *v; char *s; if(count(runq->argv->next->words)!=1){ Xerror1("variable name not singleton!"); return; } - s=runq->argv->next->words->word; + s = runq->argv->next->words->word; deglob(s); - a=runq->argv->next->next->words; - v=vlook(s)->val; - a=subwords(v, count(v), runq->argv->words, a); + a = runq->argv->next->next->words; + v = vlook(s)->val; + a = subwords(v, count(v), runq->argv->words, a); poplist(); poplist(); - runq->argv->words=a; + runq->argv->words = a; } -void Xcount(void){ + +void +Xcount(void) +{ word *a; char *s, *t; int n; @@ -617,112 +730,102 @@ void Xcount(void){ Xerror1("variable name not singleton!"); return; } - s=runq->argv->words->word; + s = runq->argv->words->word; deglob(s); - n=0; - for(t=s;'0'<=*t && *t<='9';t++) n=n*10+*t-'0'; + n = 0; + for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; if(n==0 || *t){ - a=vlook(s)->val; - itoa(num, count(a)); + a = vlook(s)->val; + inttoascii(num, count(a)); } else{ - a=vlook("*")->val; - itoa(num, a && 1<=n && n<=count(a)?1:0); + a = vlook("*")->val; + inttoascii(num, a && 1<=n && n<=count(a)?1:0); } poplist(); pushword(num); } -void Xlocal(void){ + +void +Xlocal(void) +{ if(count(runq->argv->words)!=1){ Xerror1("variable name must be singleton\n"); return; } deglob(runq->argv->words->word); - runq->local=newvar(strdup(runq->argv->words->word), runq->local); - runq->local->val=copywords(runq->argv->next->words, (word *)0); - runq->local->changed=1; + runq->local = newvar(strdup(runq->argv->words->word), runq->local); + runq->local->val = copywords(runq->argv->next->words, (word *)0); + runq->local->changed = 1; poplist(); poplist(); } -void Xunlocal(void){ - var *v=runq->local, *hid; - if(v==0) panic("Xunlocal: no locals!", 0); - runq->local=v->next; - hid=vlook(v->name); - hid->changed=1; + +void +Xunlocal(void) +{ + var *v = runq->local, *hid; + if(v==0) + panic("Xunlocal: no locals!", 0); + runq->local = v->next; + hid = vlook(v->name); + hid->changed = 1; efree(v->name); freewords(v->val); efree((char *)v); } -void freewords(word *w) + +void +freewords(word *w) { word *nw; while(w){ efree(w->word); - nw=w->next; + nw = w->next; efree((char *)w); - w=nw; + w = nw; } } -void Xfn(void){ + +void +Xfn(void) +{ var *v; word *a; int end; - end=runq->code[runq->pc].i; - for(a=runq->argv->words;a;a=a->next){ - v=gvlook(a->word); - if(v->fn) codefree(v->fn); - v->fn=codecopy(runq->code); - v->pc=runq->pc+2; - v->fnchanged=1; - } - runq->pc=end; + end = runq->code[runq->pc].i; + for(a = runq->argv->words;a;a = a->next){ + v = gvlook(a->word); + if(v->fn) + codefree(v->fn); + v->fn = codecopy(runq->code); + v->pc = runq->pc+2; + v->fnchanged = 1; + } + runq->pc = end; poplist(); } -void Xdelfn(void){ + +void +Xdelfn(void) +{ var *v; word *a; - for(a=runq->argv->words;a;a=a->next){ - v=gvlook(a->word); - if(v->fn) codefree(v->fn); - v->fn=0; - v->fnchanged=1; + for(a = runq->argv->words;a;a = a->next){ + v = gvlook(a->word); + if(v->fn) + codefree(v->fn); + v->fn = 0; + v->fnchanged = 1; } poplist(); } -void Xpipe(void){ - struct thread *p=runq; - int pc=p->pc, forkid; - int lfd=p->code[pc++].i; - int rfd=p->code[pc++].i; - int pfd[2]; - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - switch(forkid=fork()){ - case -1: - Xerror("try again"); - break; - case 0: - start(p->code, pc+2, runq->local); - runq->ret=0; - close(pfd[PRD]); - pushredir(ROPEN, pfd[PWR], lfd); - break; - default: - start(p->code, p->code[pc].i, runq->local); - close(pfd[PWR]); - pushredir(ROPEN, pfd[PRD], rfd); - p->pc=p->code[pc+1].i; - p->pid=forkid; - break; - } -} -char *concstatus(char *s, char *t) + +char* +concstatus(char *s, char *t) { static char v[NSTATUS+1]; - int n=strlen(s); + int n = strlen(s); strncpy(v, s, NSTATUS); if(n<NSTATUS){ v[n]='|'; @@ -731,7 +834,10 @@ char *concstatus(char *s, char *t) v[NSTATUS]='\0'; return v; } -void Xpipewait(void){ + +void +Xpipewait(void) +{ char status[NSTATUS+1]; if(runq->pid==-1) setstatus(concstatus(runq->status, getstatus())); @@ -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(); } |