From 7e1eaee616365799cfc4cc787fdaa9448958536b Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 20 Oct 2021 14:21:06 -0700 Subject: Feat: now execs instead of exec + fork if going to exit. One quick solution to the lack of tracking deep into the command line is to note that the pattern of code emitted for an async is: Xasync |__ child (command) |__ parent (continues) The child creates a process group, as described before. If the child is a simple command, we will now "exec" as it will exit immediately after the command. This gives us the correct behavior, at least for simple cases. This also fixed pipes. However, if child has to be forked, i.e. can't be immediately execed, then I don't think this process works... --- sys/cmd/rc/exec.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'sys/cmd/rc/exec.c') 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 @@ -150,6 +150,17 @@ undoredirs(void) Xpopredir(); } +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) { -- cgit v1.2.1