aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/rc/exec.c')
-rw-r--r--src/cmd/rc/exec.c989
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();
}