diff options
Diffstat (limited to 'c/sh.c')
| -rw-r--r-- | c/sh.c | 38 |
1 files changed, 36 insertions, 2 deletions
@@ -18,6 +18,30 @@ static unsigned char tokenize(char *s, char **tok, unsigned char max) { } static unsigned char isop(char *t, char c) { return t[0] == c && t[1] == 0; } +static unsigned char iscmd(char *t, char a, char b) { + return t[0] == a && t[1] == b && t[2] == 0; +} + +/* keep the prompt's path string roughly in sync with chdir(). */ +static void set_cwd(char *cwd, char *arg) { + char *d, *s, *last; + if (arg[0] == '/') { /* absolute */ + d = cwd; s = arg; + while (*s) *d++ = *s++; + *d = 0; + } else if (arg[0] == '.' && arg[1] == '.' && arg[2] == 0) { + last = cwd; d = cwd; + while (*d) { if (*d == '/') last = d; d++; } + if (last == cwd) { cwd[0] = '/'; cwd[1] = 0; } else *last = 0; + } else if (arg[0] == '.' && arg[1] == 0) { + /* stay */ + } else { /* relative: append */ + d = cwd; while (*d) d++; + if (!(cwd[0] == '/' && cwd[1] == 0)) *d++ = '/'; + s = arg; while (*s) *d++ = *s++; + *d = 0; + } +} /* build the child command line "name\0arg1 arg2\0" at 0xA000 */ static void set_cmdline(char **tok, unsigned char start, unsigned char end) { @@ -74,22 +98,32 @@ done: void main(void) { char line[80]; char *tok[16]; + char cwd[40]; + cwd[0] = '/'; cwd[1] = 0; for (;;) { unsigned char nt, i, pipepos, c, bg; /* reap finished background jobs */ { unsigned char p; while ((p = reap())) { putc('['); putu(p); puts(" done]"); nl(); } } - puts("$ "); + puts(cwd); puts("$ "); /* read a line (echoing), stop at newline; exit on EOF */ i = 0; for (;;) { c = readc(); - if (c == EOF) return; + if (c == EOF) poweroff(); if (c == '\r' || c == '\n') { nl(); break; } if (i < 79) { line[i++] = c; putc(c); } } line[i] = 0; nt = tokenize(line, tok, 16); if (nt == 0) continue; + if (iscmd(tok[0], 'c', 'd')) { /* cd builtin */ + char *arg = (nt >= 2) ? tok[1] : "/"; + if (chdir(arg) == 0) set_cwd(cwd, arg); + else { puts("cd: no such directory"); nl(); } + continue; + } + if ((tok[0][0] == 'e' && tok[0][1] == 'x') || + (tok[0][0] == 'q' && tok[0][1] == 'u')) poweroff(); bg = 0; if (isop(tok[nt - 1], '&')) { bg = 1; nt--; if (nt == 0) continue; } pipepos = 0; |
