aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/exec.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-11-16 14:46:55 -0800
committerNicholas Noll <nbnoll@eml.cc>2021-11-16 14:46:55 -0800
commite923adef5df8077259ed9973a4bffb0e08999fbe (patch)
tree60b7bf91db2d6eb54e3777f395419d23369842b6 /src/cmd/rc/exec.c
parent29138fff8643194ec49cb79304d2a878d46c378b (diff)
chore: integrated redir code
Diffstat (limited to 'src/cmd/rc/exec.c')
-rw-r--r--src/cmd/rc/exec.c112
1 files changed, 92 insertions, 20 deletions
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index 28b6135..28941a0 100644
--- a/src/cmd/rc/exec.c
+++ b/src/cmd/rc/exec.c
@@ -168,8 +168,7 @@ undoredirs(void)
Xpopredir();
}
-static inline
-int
+static inline int
exitsnext(void)
{
Code *c = &runner->code.exe[runner->code.i];
@@ -191,8 +190,7 @@ defaultsignal(void)
signal(SIGCHLD, SIG_DFL);
}
-static inline
-void
+static inline void
setpid(Thread *job, int pid)
{
job->pid = pid;
@@ -206,8 +204,7 @@ setpid(Thread *job, int pid)
/* fork/execute helpers */
-static inline
-void
+static inline void
initchild(Thread *job, int fg)
{
int pid = getpid();
@@ -224,8 +221,7 @@ initchild(Thread *job, int fg)
clearwait(job);
}
-static inline
-void
+static inline void
initparent(Thread *job, int pid, int fg)
{
setpid(job, pid);
@@ -239,8 +235,7 @@ initparent(Thread *job, int pid, int fg)
addwait(job, pid);
}
-static
-void
+static void
xx(void)
{
popword(); // "exec"
@@ -248,32 +243,29 @@ xx(void)
Xerror("empty argument list");
return;
}
-
+ // set up file descriptors
redirect(runner->redir.end);
execute(runner->args->word, path(runner->args->word->str));
poplist();
}
-static
-int
+static int
xforkx(void)
{
int n, pid;
switch(pid=fork()){
case -1:
- Xerror("try again\n");
+ Xerror("fork failed: try again\n");
return -1;
case 0: // child
initchild(runner, 1);
-
pushword("exec");
xx();
-
- exit(2); // NOTE: unreachable: xx does not return
+ exit(2); // reach here on failed execs
+ break;
default: // parent
initparent(runner, pid, 0);
-
return pid;
}
}
@@ -286,7 +278,7 @@ pushredir(int type, int from, int to)
r->type = type;
r->from = from;
- r->to = to;
+ r->to = to;
r->link = runner->redir.end, runner->redir.end = r;
}
@@ -1080,7 +1072,7 @@ Xjoin(void)
}
s = runner->args->word->str;
- // deglob(s)
+ deglob(s);
arg = var(s)->val;
poplist();
@@ -1283,6 +1275,86 @@ Xsubshell(void)
}
void
+Xsubcmd(void)
+{
+ Io *io;
+ rune r;
+ Var *ifs;
+ Word *w, *nw;
+ int n, c, pid, pfd[2];
+ char *s, *end, *hit, *q, buf[8193];
+
+ ifs = var("ifs");
+ end = arrend(buf)-1;
+ hit = ifs->val ? ifs->val->str : "";
+
+ if(pipe(pfd)<0){
+ Xerror("pipe failed");
+ return;
+ }
+
+ switch(pid=fork()){
+ case -1:
+ Xerror("fork failed: try again");
+ close(pfd[0]), close(pfd[1]);
+ return;
+
+ case 0: // child
+ initchild(runner, 1);
+
+ close(pfd[0]);
+ run(runner->code.exe, runner->code.i+1, runner->local, 1);
+ pushredir(Ropen, pfd[1], 1);
+ break;
+
+ default: // parent
+ initparent(runner, pid, 0);
+ close(pfd[1]);
+ io = openfd(pfd[0]);
+
+ s = buf;
+ w = nil;
+ while((c=get(io))!=EOF){
+ if(s != end){
+ *s++ = c;
+ for(q=hit; *q; q+=n){
+ n = utf8·decode(q, &r);
+ if(s-buf >= n && memcmp(s-n, q, n)==0){
+ s -= n;
+ goto finish;
+ }
+ }
+ continue;
+ }
+ finish:
+ if(s != buf){
+ *s = 0;
+ w = makeword(buf, w);
+ }
+ s = buf;
+ }
+ if(s != buf){
+ *s = 0;
+ w = makeword(buf, w);
+ }
+
+ waitfor(runner, pid);
+ terminate(io);
+
+ /* reverse the list */
+ while(w){
+ nw = w->link;
+ w->link = runner->args->word;
+ runner->args->word = w;
+ w = nw;
+ }
+ assert(runner->wait.status == Pdone);
+ deljob(runner);
+ runner->code.i = runner->code.exe[runner->code.i].i;
+ }
+}
+
+void
Xpipewait(void)
{
foreground(runner, 0);