#include "rc.h"
int flag[256];
Io *err;
Channel *wchan;
Thread *runq;
int ndot;
void
initpath(void)
{
char *p;
char *PATH;
Word *path, *v;
if(vlook("path")->val != nil)
return;
v = vlook("PATH")->val;
if(v == nil)
return;
PATH = strdup(v->word);
if(PATH == nil)
return;
path = nil;
while((p = strrchr(PATH, ':')) != nil){
*p++ = '\0';
path = newword(p, path);
}
path = newword(PATH, path);
setvar("path", path);
}
void
threadmain(int argc, char *argv[])
{
int i;
Code bootstrap[17];
char *cflag;
char rcmain[200];
Var *pmroot;
cflag = 0;
/* default to interactive mode */
flag['i']++;
ARGBEGIN{
default:
fprint(2, "usage: %s: [-seiIlvxr] [-c string] [file [args]]\n", argv0);
threadexitsall("usage");
case 'D':
pm_debug = ~0;
break;
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
wchan = threadwaitchan();
err = openfd(2);
kinit();
vinit();
notify(notifyf);
initpath();
pmroot = vlook("9pm");
if(pmroot->val == 0)
pmroot = vlook("9PM");
if(pmroot->val == 0)
pmroot = vlook("ninepm");
if(pmroot->val == 0)
pmroot = vlook("NINEPM");
if(pmroot->val == 0)
sysfatal("$9pm not set");
sprint(rcmain, "%s/lib/rcmain", pmroot->val->word);
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, "rcsh: ");
pfmt(err, s, n);
pchr(err, '\n');
flush(err);
pfmt(err, "aborting\n");
flush(err);
threadexitsall("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;
//fprint(2, "start runq=%p\n", runq);
}
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)
{
Thread *p;
Waitmsg *w;
char errbuf[ERRMAX];
Again:
while((w = recvp(wchan)) != nil){
if(w->pid==pid){
setstatus(w->msg);
free(w);
return;
}
for(p=runq->ret;p;p=p->ret)
if(p->pid==w->pid){
p->pid=-1;
strcpy(p->status, w->msg);
}
free(w);
}
rerrstr(errbuf, sizeof errbuf);
//fprint(2, "wait: err %s\n", errbuf);
if(strcmp(errbuf, "interrupted")==0)
goto Again;
}
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;
}
syntax highlighted by Code2HTML, v. 0.9.1