aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cmd/rc/exec.c25
-rw-r--r--sys/cmd/rc/lex.c2
-rw-r--r--sys/cmd/rc/sys.c2
-rw-r--r--sys/cmd/rc/wait.c22
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);