aboutsummaryrefslogtreecommitdiffstats
path: root/c/sh.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/sh.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/c/sh.c b/c/sh.c
index c24ed9f..8aa619e 100644
--- a/c/sh.c
+++ b/c/sh.c
@@ -34,9 +34,10 @@ static void set_cmdline(char **tok, unsigned char start, unsigned char end) {
*p = 0;
}
-/* run tok[start..end): parse its own >/< redirects, honor forced in/out. */
+/* run tok[start..end): parse its own >/< redirects, honor forced in/out.
+ If bg, launch in the background (don't wait; leave fds to the child). */
static void run(char **tok, unsigned char start, unsigned char end,
- unsigned char infd, unsigned char outfd) {
+ unsigned char infd, unsigned char outfd, unsigned char bg) {
unsigned char i, cmdend = end, myin = NOFD, myout = NOFD, id, pid;
for (i = start; i < end; i++) {
if (isop(tok[i], '>')) {
@@ -58,7 +59,13 @@ static void run(char **tok, unsigned char start, unsigned char end,
else if (outfd != NOFD) setout(outfd);
exec(id);
}
- wait();
+ if (bg) { putc('['); putu(pid); puts("]"); nl(); return; } /* background */
+ /* wait for THIS child; report any background jobs that finish meanwhile */
+ for (;;) {
+ unsigned char r = wait();
+ if (r == pid || r == NOFD) break;
+ putc('['); putu(r); puts(" done]"); nl();
+ }
done:
if (myin != NOFD) close(myin);
if (myout != NOFD) close(myout);
@@ -68,7 +75,9 @@ void main(void) {
char line[80];
char *tok[16];
for (;;) {
- unsigned char nt, i, pipepos, c;
+ unsigned char nt, i, pipepos, c, bg;
+ /* reap finished background jobs */
+ { unsigned char p; while ((p = reap())) { putc('['); putu(p); puts(" done]"); nl(); } }
puts("$ ");
/* read a line (echoing), stop at newline; exit on EOF */
i = 0;
@@ -81,19 +90,21 @@ void main(void) {
line[i] = 0;
nt = tokenize(line, tok, 16);
if (nt == 0) continue;
+ bg = 0;
+ if (isop(tok[nt - 1], '&')) { bg = 1; nt--; if (nt == 0) continue; }
pipepos = 0;
for (i = 1; i < nt; i++)
if (isop(tok[i], '|')) { pipepos = i; break; }
if (pipepos) {
unsigned char pw = open("__pipe", O_WRITE);
- run(tok, 0, pipepos, NOFD, pw);
+ run(tok, 0, pipepos, NOFD, pw, 0);
close(pw);
{ unsigned char pr = open("__pipe", O_READ);
- run(tok, pipepos + 1, nt, pr, NOFD);
+ run(tok, pipepos + 1, nt, pr, NOFD, 0);
close(pr); }
fremove("__pipe");
} else {
- run(tok, 0, nt, NOFD, NOFD);
+ run(tok, 0, nt, NOFD, NOFD, bg);
}
}
}