aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/exec.c')
-rw-r--r--sys/cmd/rc/exec.c188
1 files changed, 98 insertions, 90 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c
index 80cd645..d78cb5d 100644
--- a/sys/cmd/rc/exec.c
+++ b/sys/cmd/rc/exec.c
@@ -31,10 +31,10 @@ static
void
pushword(char *str)
{
- if(!proc->args)
+ if(!runner->args)
fatal("attempt to push on empty argument stack\n");
- proc->args->word = makeword(str, proc->args->word);
+ runner->args->word = makeword(str, runner->args->word);
}
static
@@ -42,14 +42,14 @@ void
popword(void)
{
Word *w;
- if(!proc->args)
+ if(!runner->args)
fatal("tried to pop word on empty argument stack\n");
- w = proc->args->word;
+ w = runner->args->word;
if(!w)
fatal("tried to pop word but nothing there\n");
- proc->args->word = w->link;
+ runner->args->word = w->link;
efree(w->str);
efree(w);
}
@@ -101,21 +101,21 @@ pushlist(void)
List *stack = emalloc(sizeof(*stack));
stack->word = nil;
- stack->link = proc->args;
+ stack->link = runner->args;
- proc->args = stack;
+ runner->args = stack;
}
static
void
poplist(void)
{
- List *stack = proc->args;
+ List *stack = runner->args;
if(!stack)
fatal("attempted to pop an empty argument stack\n");
freelist(stack->word);
- proc->args = stack->link;
+ runner->args = stack->link;
efree(stack);
}
@@ -140,12 +140,12 @@ void
xx(void)
{
popword(); // "exec"
- if(!proc->args->word){
+ if(!runner->args->word){
Xerror("empty argument list");
return;
}
- execute(proc->args->word, path(proc->args->word->str));
+ execute(runner->args->word, path(runner->args->word->str));
poplist();
}
@@ -160,15 +160,15 @@ xforkx(void)
case -1:
return -1;
case 0: // child
- clearwait(proc);
+ clearwait(runner);
if(shell.interactive){
- proc->pid = getpid();
- if(proc->pgid <= 0)
- proc->pgid = proc->pid;
+ runner->pid = getpid();
+ if(runner->pgid <= 0)
+ runner->pgid = runner->pid;
- setpgid(pid, proc->pgid);
- tcsetpgrp(0, proc->pgid);
+ setpgid(pid, runner->pgid);
+ tcsetpgrp(0, runner->pgid);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
@@ -181,16 +181,16 @@ xforkx(void)
pushword("exec");
xx();
- exit(1); // NOTE: xx does not return!
+ exit(2); // NOTE: xx does not return!
/*unreachable*/
default: // parent
- addwait(proc, pid);
+ addwait(runner, pid);
/* ensure the state matches for parent and child */
- proc->pid = pid;
- if(proc->pgid <= 0)
- proc->pgid = pid;
- setpgid(pid, proc->pgid);
+ runner->pid = pid;
+ if(runner->pgid <= 0)
+ runner->pgid = pid;
+ setpgid(pid, runner->pgid);
return pid;
}
@@ -205,9 +205,9 @@ pushredir(int type, int from, int to)
r->type = type;
r->from = from;
r->to = to;
- r->link = proc->redir;
+ r->link = runner->redir;
- proc->redir = r;
+ runner->redir = r;
}
/* byte code */
@@ -219,17 +219,30 @@ run(Code *c, int pc, Var *local)
new->code.i = pc;
new->code.exe = copycode(c);
- new->args = nil;
- new->local = local;
+
new->cmd.path = nil;
new->cmd.io = nil;
+
+ new->args = nil;
+ new->local = local;
+ new->redir = nil;
+
+ new->flag.i = 0;
new->flag.eof = 0;
- new->line = 1;
- new->link = proc;
+ new->wait.status = 0;
+ new->wait.len = 0;
+ new->wait.cap = 0;
+ new->wait.on = nil;
+
+ new->status = 0;
new->pgid = new->pid = -1;
- proc = new;
+ new->line = 0;
+ new->link = runner;
+ new->next = nil;
+
+ runner = new;
}
// -----------------------------------------------------------------------
@@ -307,12 +320,12 @@ xdot(void)
}
#endif
/* get input file */
- if(!proc->args->word){
+ if(!runner->args->word){
Xerror("usage: . [-i] file [arg ...]\n");
return;
}
- base = strdup(proc->args->word->str);
+ base = strdup(runner->args->word->str);
popword();
for(fd=-1, p=path(base); p; p = p->link){
strcpy(file, p->str);
@@ -326,23 +339,23 @@ xdot(void)
}
if(fd<0){
- print(errio, "%s: ", base);
+ print(shell.err, "%s: ", base);
//setstatus("can't open");
Xerror(".: can't open\n");
return;
}
/* set up for a new command loop */
- old = proc; // store pointer to old code
+ old = runner; // store pointer to old code
run(dotcmd, 1, nil);
/* operations on new command stack */
pushredir(Rclose, fd, 0);
- proc->cmd.path = base;
- proc->cmd.io = openfd(fd);
+ runner->cmd.path = base;
+ runner->cmd.io = openfd(fd);
/* push $* value */
pushlist();
- proc->args->word = old->args->word;
+ runner->args->word = old->args->word;
/* free caller's copy of $* */
argv = old->args;
@@ -361,7 +374,7 @@ xjob(void)
int i;
Thread *job;
- for(i = 0, job = shell.jobs; job; job = job->next)
+ for(i=0, job = shell.jobs; job; job = job->next, i++)
report(job,i);
poplist();
@@ -376,27 +389,23 @@ xfg(void)
popword(); // fg
/* get input job id */
- if(!proc->args->word){
- print(errio, "usage: fg [pid|\%num]\n");
+ if(!runner->args->word){
+ print(shell.err, "usage: fg [pid|\%num]\n");
poplist();
return;
}
- i = atoi(proc->args->word->str);
+ i = atoi(runner->args->word->str);
popword(); // [jobid]
for(job=shell.jobs; i > 0; job=job->next, --i)
;
- assert(!job->flag.done);
-
- addwait(job, job->pid);
- job->flag.stop = 0;
poplist(); // this goes here?
- job->link = proc, proc = job; // XXX: can this leave orphans?
+ wakeup(job);
+ job->link = runner, runner = job; // XXX: can this leave zombies?
foreground(job, 1);
- printf("hi\n");
}
void
@@ -434,8 +443,8 @@ xboot(int argc, char *argv[])
/* main interpreter loop */
for(;;){
- proc->code.i++;
- (*proc->code.exe[proc->code.i-1].f)();
+ runner->code.i++;
+ (*runner->code.exe[runner->code.i-1].f)();
}
}
@@ -451,52 +460,55 @@ Xmark(void)
void
Xerror(char *msg)
{
- print(errio, "rc: %s", msg);
- flush(errio);
- while(!proc->flag.i)
+ print(shell.err, "rc: %s", msg);
+ flush(shell.err);
+ while(!runner->flag.i)
Xreturn();
}
void
Xreturn(void)
{
- Thread *run = proc;
+ Thread *run = runner;
+ switch(run->wait.status){
/*
* If our job is still running we must:
* 1. move program one step back to rerun Xreturn upon recall
* 2. return to our calling thread
* 3. don't free!
*/
- if(run->flag.stop){
+ case PStop:
run->code.i--;
- proc = run->link;
+ runner = run->link;
return;
- }
-
/*
* If our job has finished:
* 1. remove from our list
- * 2. clean up its memory!
+ * 2. continue to clean up its memory
*/
- if(run->flag.done)
+ case PDone:
deljob(run);
+ /* fallthrough */
+ default:
+ ;
+ }
while(run->args)
poplist();
freecode(run->code.exe);
- efree(run->wait.pid);
+ efree(run->wait.on);
- proc = run->link;
+ runner = run->link;
efree(run);
- if(!proc)
+ if(!runner)
exit(0);
}
void
Xword(void)
{
- pushword(proc->code.exe[proc->code.i++].s);
+ pushword(runner->code.exe[runner->code.i++].s);
}
void
@@ -506,18 +518,18 @@ Xdollar(void)
char *s, *t;
Word *a, *star;
- if(count(proc->args->word)!=1){
+ if(count(runner->args->word)!=1){
Xerror("variable name not singleton!\n");
return;
}
- s = proc->args->word->str;
+ s = runner->args->word->str;
// deglob(s);
n = 0;
for(t = s;'0'<=*t && *t<='9';t++)
n = n*10+*t-'0';
- a = proc->args->link->word;
+ a = runner->args->link->word;
if(n==0 || *t)
a = copywords(var(s)->val, a);
@@ -532,7 +544,7 @@ Xdollar(void)
}
poplist();
- proc->args->word = a;
+ runner->args->word = a;
}
void
@@ -540,22 +552,22 @@ Xassign(void)
{
Var *v;
- if(count(proc->args->word)!=1){
+ if(count(runner->args->word)!=1){
Xerror("variable name not singleton!\n");
return;
}
//deglob(runq->argv->words->word);
- v = var(proc->args->word->str);
+ v = var(runner->args->word->str);
poplist();
//globlist();
freewords(v->val);
- v->val = proc->args->word;
+ v->val = runner->args->word;
v->new = 1;
if(v->update)
v->update(v);
- proc->args->word = nil;
+ runner->args->word = nil;
poplist();
}
@@ -566,8 +578,8 @@ Xreadcmd(void)
Thread *root;
Word *prompt;
- flush(errio);
- root = proc;
+ flush(shell.err);
+ root = runner;
if(yyparse()){
exit(1);
@@ -576,22 +588,22 @@ Xreadcmd(void)
run(compiled, 1, root->local);
}
- // killzombies();
+ killzombies();
freeparsetree();
}
void
Xlocal(void)
{
- if(count(proc->args->word)!=1){
+ if(count(runner->args->word)!=1){
Xerror("variable name must be singleton\n");
return;
}
//deglob(shell->args->word->str);
- proc->local = makevar(strdup(proc->args->word->str), proc->local);
- proc->local->val = copywords(proc->args->link->word, nil);
- proc->local->new = 1;
+ runner->local = makevar(strdup(runner->args->word->str), runner->local);
+ runner->local->val = copywords(runner->args->link->word, nil);
+ runner->local->new = 1;
poplist();
poplist();
@@ -600,13 +612,11 @@ Xlocal(void)
void
Xunlocal(void)
{
- Var *v = proc->local, *hide;
+ Var *v = runner->local, *hide;
if(!v)
fatal("Xunlocal: no locals!\n", 0);
- printf("unlocal\n");
-
- proc->local = v->link;
+ runner->local = v->link;
hide = var(v->name);
hide->new = 1;
@@ -623,19 +633,18 @@ Xbasic(void)
int pid, status;
struct Builtin *b;
- arg = proc->args->word;
+ arg = runner->args->word;
if(!arg){
Xerror("empty argument list\n");
return;
}
- /* print(errio, "recieved arg: %v\n", arg); // for debugging */
- flush(errio);
+ flush(shell.err);
v = var(arg->str);
if(v->func){
- // xfunc(v);
return;
}
+
// see if it matches a builtin
for(b = builtin; b->name; b++){
if(strcmp(b->name, arg->str)==0){
@@ -645,8 +654,7 @@ Xbasic(void)
}
/* if we are here then it's an external command */
- killzombies();
- addjob(proc);
+ addjob(runner);
// run the external command
if((pid = xforkx()) < 0) {
@@ -657,9 +665,9 @@ Xbasic(void)
poplist();
if(!shell.interactive)
- waitall(proc);
+ waitall(runner);
- foreground(proc, 0); // waits for child
+ foreground(runner, 0); // waits for child
}
void