From 566d54fe549286895fdef8aa9f385686405dd290 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 13 Oct 2021 16:46:20 -0700 Subject: RM(rc): old code. too many assumptions baked in --- sys/cmd/rc/exec.c | 1013 ----------------------------------------------------- 1 file changed, 1013 deletions(-) delete mode 100644 sys/cmd/rc/exec.c (limited to 'sys/cmd/rc/exec.c') diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c deleted file mode 100644 index fdb63cf..0000000 --- a/sys/cmd/rc/exec.c +++ /dev/null @@ -1,1013 +0,0 @@ -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -/* - * Start executing the given code at the given pc with the given redirection - */ -char *argv0="rc"; -int ndot; -int lastc; -int kidpid; -int mypid; - -Thread *runq; -Code *codebuf; /* compiler output */ -int ntrap; /* number of outstanding traps */ -int trap[NSIG]; /* number of outstanding traps per type */ -int eflagok; /* kludge flag so that -e doesn't exit in startup */ - -char **argp; -char **args; -int nerror; /* number of errors encountered during compilation */ - -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) -{ - if(runq->argv==0) - panic("pushword but no argv!", 0); - runq->argv->words = newword(wd, runq->argv->words); -} - -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; - efree(p->word); - efree((char *)p); -} - -void -freelist(Word *w) -{ - Word *nw; - while(w){ - nw = w->next; - efree(w->word); - efree((char *)w); - w = nw; - } -} - -void -pushlist(void) -{ - Words *p = new(Words); - p->next = runq->argv; - p->words = 0; - runq->argv = p; -} - -void -poplist(void) -{ - Words *p = runq->argv; - if(p==0) - panic("poplist but no argv", 0); - freelist(p->words); - runq->argv = p->next; - efree((char *)p); -} - -int -count(Word *w) -{ - int n; - 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; - return v; -} -/* - * get command line flags, initialize keywords & traps. - * get values from environment. - * set $pid, $cflag, $* - * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*) - * start interpreting code - */ -int -main(int argc, char *argv[]) -{ - Code bootstrap[32]; - char num[12], *rcmain; - int i; - - 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); - kinit(); - Trapinit(); - Vinit(); - 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; - memset(bootstrap, 0, sizeof bootstrap); - 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++].s="*"; - 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; - start(bootstrap, 1, (Var *)0); - /* prime bootstrap argv */ - pushlist(); - argv0 = strdup(argv[0]); - for(i = argc-1;i!=0;--i) pushword(argv[i]); - for(;;){ - if(flag['r']) - pfnc(err, runq); - runq->pc++; - (*runq->code[runq->pc-1].f)(); - if(ntrap) - dotrap(); - } - return 0; /* not reached; silence OS X Lion gcc */ -} -/* - * Opcode routines - * Arguments on stack (...) - * Arguments in line [...] - * Code in line with jump around {...} - * - * Xappend(file)[fd] open file to append - * Xassign(name, val) assign val to name - * Xasync{... Xexit} make thread for {}, no wait - * Xbackq{... Xreturn} make thread for {}, push stdout - * Xbang complement condition - * Xcase(pat, value){...} exec code on match, leave (value) on - * stack - * Xclose[i] close file descriptor - * Xconc(left, right) concatenate, push results - * Xcount(name) push var count - * Xdelfn(name) delete function definition - * Xdeltraps(names) delete named traps - * Xdol(name) get variable value - * Xqdol(name) concatenate variable components - * Xdup[i j] dup file descriptor - * Xexit rc exits with status - * Xfalse{...} execute {} if false - * Xfn(name){... Xreturn} define function - * Xfor(var, list){... Xreturn} for loop - * Xjump[addr] goto - * Xlocal(name, val) create local variable, assign value - * Xmark mark stack - * Xmatch(pat, str) match pattern, set status - * Xpipe[i j]{... Xreturn}{... Xreturn} construct a pipe between 2 new threads, - * wait for both - * 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 - * Xsimple(args) run command and wait - * Xreturn kill thread - * Xsubshell{... Xexit} execute {} in a subshell and wait - * Xtrue{...} execute {} if true - * Xunlocal delete local variable - * Xword[string] push string - * Xwrite(file)[fd] open file to write - */ - -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; - } - file = runq->argv->words->word; - if((f = open(file, 1))<0 && (f = Creat(file))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - Seek(f, 0L, 2); - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -void -Xsettrue(void) -{ - setstatus(""); -} - -void -Xbang(void) -{ - setstatus(truestatus()?"false":""); -} - -void -Xclose(void) -{ - pushredir(RCLOSE, runq->code[runq->pc].i, 0); - runq->pc++; -} - -void -Xdup(void) -{ - pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i); - runq->pc+=2; -} - -void -Xeflag(void) -{ - if(eflagok && !truestatus()) Xexit(); -} - -void -Xexit(void) -{ - struct Var *trapreq; - struct Word *starval; - static int beenhere = 0; - if(getpid()==mypid && !beenhere){ - trapreq = vlook("sigexit"); - if(trapreq->fn){ - beenhere = 1; - --runq->pc; - 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; - return; - } - } - Exit(getstatus()); -} - -void -Xfalse(void) -{ - if(truestatus()) runq->pc = runq->code[runq->pc].i; - else runq->pc++; -} -int ifnot; /* dynamic if not flag */ - -void -Xifnot(void) -{ - if(ifnot) - runq->pc++; - else - runq->pc = runq->code[runq->pc].i; -} - -void -Xjump(void) -{ - runq->pc = runq->code[runq->pc].i; -} - -void -Xmark(void) -{ - pushlist(); -} - -void -Xpopm(void) -{ - poplist(); -} - -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; - } - file = runq->argv->words->word; - if((f = open(file, 0))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -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); - efree((char *)rp); -} - -void -Xreturn(void) -{ - struct Thread *p = runq; - turfredir(); - while(p->argv) poplist(); - codefree(p->code); - runq = p->ret; - efree((char *)p); - if(runq==0) - Exit(getstatus()); -} - -void -Xtrue(void) -{ - if(truestatus()) runq->pc++; - else runq->pc = runq->code[runq->pc].i; -} - -void -Xif(void) -{ - ifnot = 1; - if(truestatus()) runq->pc++; - else runq->pc = runq->code[runq->pc].i; -} - -void -Xwastrue(void) -{ - ifnot = 0; -} - -void -Xword(void) -{ - pushword(runq->code[runq->pc++].s); -} - -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; - } - file = runq->argv->words->word; - if((f = Creat(file))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -char* -list2str(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 -Xmatch(void) -{ - Word *p; - char *subject; - subject = list2str(runq->argv->words); - setstatus("no match"); - for(p = runq->argv->next->words;p;p = p->next) - if(match(subject, p->word, '\0')){ - setstatus(""); - break; - } - efree(subject); - poplist(); - poplist(); -} - -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){ - if(match(s, p->word, '\0')){ - ok = 1; - break; - } - } - efree(s); - if(ok) - runq->pc++; - else - runq->pc = runq->code[runq->pc].i; - poplist(); -} - -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); - buf = emalloc(strlen(lp->word)+strlen(rp->word)+1); - strcpy(buf, lp->word); - strcat(buf, rp->word); - 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); - if(lc!=0 || rc!=0){ - if(lc==0 || rc==0){ - Xerror1("null list in concatenation"); - return; - } - if(lc!=1 && rc!=1 && lc!=rc){ - Xerror1("mismatched list lengths in concatenation"); - return; - } - vp = conclist(lp, rp, vp); - } - poplist(); - poplist(); - runq->argv->words = vp; -} - -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); - poplist(); - globlist(); - freewords(v->val); - v->val = runq->argv->words; - v->changed = 1; - if(v->changefn) - v->changefn(v); - runq->argv->words = 0; - poplist(); -} -/* - * copy arglist a, adding the copy to the front of 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; - return v; -} - -void -Xdol(void) -{ - Word *a, *star; - char *s, *t; - int n; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - 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; - if(n==0 || *t) - a = copywords(vlook(s)->val, a); - else{ - star = vlook("*")->val; - if(star && 1<=n && n<=count(star)){ - while(--n) star = star->next; - a = newword(star->word, a); - } - } - poplist(); - runq->argv->words = a; -} - -void -Xqdol(void) -{ - Word *a, *p; - char *s; - int n; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->words->word; - deglob(s); - a = vlook(s)->val; - poplist(); - n = count(a); - if(n==0){ - pushword(""); - return; - } - 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){ - strcat(s, " "); - strcat(s, p->word); - } - } - else - s[0]='\0'; - pushword(s); - efree(s); -} - -Word* -copynwords(Word *a, Word *tail, int n) -{ - Word *v, **end; - - v = 0; - end = &v; - while(n-- > 0){ - *end = newword(a->word, 0); - end = &(*end)->next; - a = a->next; - } - *end = tail; - return v; -} - -Word* -subwords(Word *val, int len, Word *sub, Word *a) -{ - int n, m; - char *s; - if(!sub) - return a; - a = subwords(val, len, sub->next, a); - s = sub->word; - deglob(s); - m = 0; - n = 0; - while('0'<=*s && *s<='9') - n = n*10+ *s++ -'0'; - if(*s == '-'){ - if(*++s == 0) - m = len - n; - else{ - while('0'<=*s && *s<='9') - m = m*10+ *s++ -'0'; - m -= n; - } - } - if(n<1 || n>len || m<0) - return a; - if(n+m>len) - m = len-n; - while(--n > 0) - val = val->next; - return copynwords(val, a, m+1); -} - -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; - deglob(s); - 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; -} - -void -Xcount(void) -{ - Word *a; - char *s, *t; - int n; - char num[12]; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->words->word; - deglob(s); - n = 0; - for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; - if(n==0 || *t){ - a = vlook(s)->val; - inttoascii(num, count(a)); - } - else{ - a = vlook("*")->val; - inttoascii(num, a && 1<=n && n<=count(a)?1:0); - } - poplist(); - pushword(num); -} - -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; - 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; - efree(v->name); - freewords(v->val); - efree((char *)v); -} - -void -freewords(Word *w) -{ - Word *nw; - while(w){ - efree(w->word); - nw = w->next; - efree((char *)w); - w = nw; - } -} - -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; - poplist(); -} - -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; - } - poplist(); -} - -char* -concstatus(char *s, char *t) -{ - static char v[NSTATUS+1]; - int n = strlen(s); - strncpy(v, s, NSTATUS); - if(npid==-1) - setstatus(concstatus(runq->status, getstatus())); - else{ - strncpy(status, getstatus(), NSTATUS); - status[NSTATUS]='\0'; - Waitfor(runq->pid, 1); - runq->pid=-1; - setstatus(concstatus(getstatus(), status)); - } -} - -void -Xrdcmds(void) -{ - struct Thread *p = runq; - Word *prompt; - flush(err); - nerror = 0; - if(flag['s'] && !truestatus()) - pfmt(err, "status=%v\n", vlook("status")->val); - if(runq->iflag){ - prompt = vlook("prompt")->val; - if(prompt) - promptstr = prompt->word; - else - promptstr="% "; - } - Noerror(); - if(yyparse()){ - if(!p->iflag || p->eof && !Eintr()){ - if(p->cmdfile) - efree(p->cmdfile); - closeio(p->cmdfd); - Xreturn(); /* should this be omitted? */ - } - else{ - if(Eintr()){ - pchr(err, '\n'); - p->eof = 0; - } - --p->pc; /* go back for next command */ - } - } - else{ - ntrap = 0; /* avoid double-interrupts during blocked writes */ - --p->pc; /* re-execute Xrdcmds after codebuf runs */ - start(codebuf, 1, runq->local); - } - freenodes(); -} - -void -Xerror(char *s) -{ - if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s: %r\n", s); - else - pfmt(err, "rc (%s): %s: %r\n", argv0, s); - flush(err); - setstatus("error"); - while(!runq->iflag) Xreturn(); -} - -void -Xerror1(char *s) -{ - if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s\n", s); - else - pfmt(err, "rc (%s): %s\n", argv0, s); - flush(err); - setstatus("error"); - while(!runq->iflag) Xreturn(); -} - -void -setstatus(char *s) -{ - setvar("status", newword(s, (Word *)0)); -} - -char* -getstatus(void) -{ - Var *status = vlook("status"); - return status->val?status->val->word:""; -} - -int -truestatus(void) -{ - char *s; - for(s = getstatus();*s;s++) - if(*s!='|' && *s!='0') - return 0; - return 1; -} - -void -Xdelhere(void) -{ - Unlink(runq->code[runq->pc++].s); -} - -void -Xfor(void) -{ - if(runq->argv->words==0){ - poplist(); - 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->pc++; - } -} - -void -Xglob(void) -{ - globlist(); -} -- cgit v1.2.1