diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/cmd/rc/exec.c | 25 | ||||
-rw-r--r-- | sys/cmd/rc/lex.c | 2 | ||||
-rw-r--r-- | sys/cmd/rc/sys.c | 2 | ||||
-rw-r--r-- | sys/cmd/rc/wait.c | 22 |
4 files changed, 44 insertions, 7 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c index f9af866..eede516 100644 --- a/sys/cmd/rc/exec.c +++ b/sys/cmd/rc/exec.c @@ -151,6 +151,17 @@ undoredirs(void) } static inline +int +exitsnext(void) +{ + Code *c = &runner->code.exe[runner->code.i]; + while(c->f == Xpopredir) + c++; + + return c->f == Xexit; +} + +static inline void defaultsignal(void) { @@ -507,8 +518,8 @@ xfg(void) poplist(); // this goes here? wakeup(job); - foreground(job, 1); job->caller = runner, runner = job; // XXX: can this leave zombies? + foreground(job, 1); } void @@ -778,7 +789,7 @@ Xpipe(void) initchild(runner,1); /* child 0 (writer) forked process */ - run(runner->code.exe, pc+2, runner->local, 0); + run(runner->code.exe, pc+2, runner->local, 1); runner->caller = nil; close(pfd[0]); @@ -789,10 +800,12 @@ Xpipe(void) initparent(runner,pid,0); /* child 1 (reader) subprocess*/ - run(runner->code.exe, runner->code.exe[pc].i, runner->local, 0); + run(runner->code.exe, runner->code.exe[pc].i, runner->local, 1); close(pfd[1]); pushredir(Ropen, pfd[0], rfd); + + orig->code.i = orig->code.exe[pc+1].i; break; } } @@ -825,7 +838,11 @@ Xbasic(void) } /* if we are here then it's an external command */ - // TODO: check for if we will exit, don't need to fork, just exec + if(exitsnext()){ // if we exit immediately, no need to fork + pushword("exec"); + xx(); + Xexit(); + } // run the external command if((pid = xforkx()) < 0) { diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c index 373edd5..eb3a268 100644 --- a/sys/cmd/rc/lex.c +++ b/sys/cmd/rc/lex.c @@ -209,7 +209,7 @@ yylex(void) node->type = Tpipe; node->redir.fd[0] = 1; - node->redir.fd[1] = 1; + node->redir.fd[1] = 0; goto redir; case '>': diff --git a/sys/cmd/rc/sys.c b/sys/cmd/rc/sys.c index 496c2e6..a24545f 100644 --- a/sys/cmd/rc/sys.c +++ b/sys/cmd/rc/sys.c @@ -99,6 +99,8 @@ redirect(Redir *r) switch(r->type){ case Ropen: if(r->from != r->to){ + dup2(r->from, r->to); + close(r->from); } break; case Rdup: diff --git a/sys/cmd/rc/wait.c b/sys/cmd/rc/wait.c index 4d45e4b..911601c 100644 --- a/sys/cmd/rc/wait.c +++ b/sys/cmd/rc/wait.c @@ -27,6 +27,10 @@ await(int pid4, int opt, struct WaitMsg *msg) /* event loop */ for(;;){ if((pid = wait4(pid4, &status, opt, &ru)) <= 0){ + if(errno == ECHILD){ + msg->pid = -1; + return 1; + } msg->pid = 0; perror("failed wait4"); return 0; @@ -168,9 +172,16 @@ waitall(Thread *job) struct WaitMsg msg; while(shouldwait(job) && await(-job->pgid, WUNTRACED, &msg)){ - if(msg.pid == 0){ + switch(msg.pid){ + case 0: // error perror("wait job"); return 0; + case -1: // no children: assume they have exited + job->wait.status = Pdone; + clearwait(job); + return 1; + default: + ; } notify(job, msg); @@ -186,9 +197,16 @@ waitfor(Thread *job, int pid) struct WaitMsg msg; while(shouldwait(job) && await(-job->pgid, WUNTRACED, &msg)){ - if(msg.pid == 0){ + switch(msg.pid){ + case 0: // error perror("wait for"); return 0; + case -1: // no children: assume they have exited + job->wait.status = Pdone; + clearwait(job); + return 1; + default: + ; } notify(job, msg); |