diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
| commit | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch) | |
| tree | c6e220ba61db3a6ea4052e6841296d829654e664 /utils/rcsh/main.c | |
| parent | 46439007cf417cbd9ac8049bb4122c890097a0fa (diff) | |
20060303
Diffstat (limited to 'utils/rcsh/main.c')
| -rw-r--r-- | utils/rcsh/main.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/utils/rcsh/main.c b/utils/rcsh/main.c new file mode 100644 index 00000000..93cd2951 --- /dev/null +++ b/utils/rcsh/main.c @@ -0,0 +1,228 @@ +#include "rc.h" + +int flag[256]; +Io *err; +char *argv0; + +Thread *runq; +int ndot; + + +void +main(int argc, char *argv[]) +{ + int i; + Code bootstrap[17]; + char *cflag, *cp; + char rcmain[200]; + Var *infroot; + char **p; + + cflag = 0; + + /* default to interactive mode */ + flag['i']++; + + /* hack for DOS-style options, when rcsh started from MS-land */ + for (p = argv+1; *p && **p == '/'; p++) + **p = '-'; + + argv0 = *argv; + ARGBEGIN{ + default: + fprint(2, "usage: %s: [-seiIlvxr] [-c string] [file [args]]\n", argv0); + exits("usage"); + case 'e': flag['e']++; break; + case 'c': cflag = ARGF(); break; + case 'i': flag['i']++; break; + case 'I': flag['i'] = 0; break; + case 'l': flag['l']++; break; + case 'r': flag['r']++; break; + case 's': flag['s']++; break; + case 'S': flag['S']++; break; /* sub shell */ + case 'v': flag['v']++; break; + case 'V': flag['V']++; break; + case 'x': flag['x']++; break; + }ARGEND + + err = openfd(2); + + kinit(); + vinit(); + + cp = ROOT; + if(0 && strlen(argv0)) + sprint(rcmain, "%s/../lib/rcmain", argv0); + else{ + infroot = vlook("ROOT"); + if(infroot->val) + cp = infroot->val->word; + } + sprint(rcmain, "%s/utils/lib/rcmain", cp); + + setvar("rcname", newword(argv0, 0)); + if(cflag) + setvar("cflag", newword(cflag, 0)); + else + setvar("cflag", 0); + + /* bootstrap == . rcmain $* */ + 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++].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, 0); + pushlist(); + 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.ref) + dotrap(); + } +} + +void +panic(char *s, int n) +{ + pfmt(err, "rc: "); + pfmt(err, s, n); + pchr(err, '\n'); + flush(err); + pfmt(err, "aborting\n"); + flush(err); + exits("aborting"); +} + +void +setstatus(char *s) +{ + setvar("status", newword(s, 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; +} + +char * +concstatus(char *s, char *t) +{ + static char v[NSTATUS+1]; + int n=strlen(s); + strncpy(v, s, NSTATUS); + if(n<NSTATUS){ + v[n]='|'; + strncpy(v+n+1, t, NSTATUS-n-1); + } + v[NSTATUS]='\0'; + return v; +} + +/* + * Start executing the given code at the given pc with the given redirection + */ +void +start(Code *c, int pc, Var *local) +{ + Thread *p = new(Thread); + + memset(p, 0, sizeof(Thread)); + p->code = codecopy(c); + p->pc = pc; + if(runq) { + p->redir = runq->redir; + p->startredir = runq->redir; + } + p->local = local; + p->lineno = 1; + p->ret = runq; + runq=p; +} + +void +execcmds(Io *f) +{ + static Code rdcmds[4]; + static int first=1; + + if(first){ + 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; +} + +void +waitfor(uint pid) +{ + int e; + char estr[64]; + + e = procwait(pid); + if(e != 0) { + sprint(estr, "error code %d", e); + setstatus(estr); + } else + setstatus(""); +} + +char ** +procargv(char *s0, char *s1, char *s2, char *s3, Word *w) +{ + int n, i; + Word *p; + char **argv; + + for(p=w,n=5; p; p=p->next,n++); + ; + + argv = malloc(n*sizeof(char*)); + i = 0; + if(s0) + argv[i++] = s0; + if(s1) + argv[i++] = s1; + if(s2) + argv[i++] = s2; + if(s3) + argv[i++] = s3; + for(p=w; p; p=p->next) + argv[i++] = p->word; + argv[i] = 0; + return argv; +} + |
