From 47e3d475df6244a48b73421cd4210b64c392df8d Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 19 Oct 2021 09:35:59 -0700 Subject: feat(rc): cleaner process watching for each job --- sys/cmd/rc/exec.c | 188 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 98 insertions(+), 90 deletions(-) (limited to 'sys/cmd/rc/exec.c') 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 -- cgit v1.2.1