diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2021-10-21 16:53:23 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2021-10-21 16:53:23 -0700 |
commit | 3733507b090311b70ca8a2fed0c739b808f679c6 (patch) | |
tree | a964964480489b1a274a1bf1ec208243ccdf70d0 | |
parent | da77d3be2eb0785bc0c0b60c686e163d6243c744 (diff) |
feat(rc): added a few builtins
-rw-r--r-- | sys/cmd/rc/exec.c | 158 | ||||
-rw-r--r-- | sys/cmd/rc/exec.h | 5 | ||||
-rw-r--r-- | sys/cmd/rc/prompt.c | 2 | ||||
-rw-r--r-- | sys/cmd/rc/rc.h | 1 |
4 files changed, 115 insertions, 51 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c index 68d366a..e8d59c1 100644 --- a/sys/cmd/rc/exec.c +++ b/sys/cmd/rc/exec.c @@ -22,8 +22,10 @@ static struct State state; static Word nullpath = { .str="", .link=nil }; struct Builtin builtin[]={ - {".", xdot}, {"cd", xcd}, + {".", xdot}, + {"echo", xecho}, + {"exit", xexit}, {"fg", xfg}, {"jobs", xjob}, 0, @@ -358,6 +360,101 @@ count(Word *w) // ----------------------------------------------------------------------- // builtins +void +xecho(void) +{ + int fd; + Word *arg; + char *b, *s, buf[128]; + + fd = mapfd(1); + b = buf; + + popword(); // echo + + // TODO: controllable flags here + arg = runner->args->word; +printword: + s = arg->str; + while(*s){ + *b++ = *s++; + if(b == arrend(buf)-2) // always have 2 bytes available + write(fd, buf, arrlen(buf)-2), b = buf; + } + + arg = arg->link; + if(arg){ + *b++ = ' '; + goto printword; + }else{ + *b++ = '\n'; + *b++ = 0; + /* fallthrough */ + } + write(fd, buf, b-buf); + + poplist(); +} + +void +xexit(void) +{ + Word *arg; + + popword(); // exit + arg = runner->args->word; + switch(count(arg)){ + default: + print(shell.err, "invalid number of arguments to exit, exiting anyways\n"); + case 0: + Xexit(); + } + /* unreachable */ +} + +void +xcd(void) +{ + Word *arg; + Word *cdpath; + char dir[512]; + + popword(); // cd + + arg = runner->args->word; + switch(count(arg)){ + default: + print(shell.err, "usage: cd [directory]\n"); + break; + case 0: + arg = var("home")->val; + if(count(arg) >= 1){ + if(chdir(arg->str) < 0) + print(shell.err, "failed cd: %s\n", strerror(errno)); + }else{ + print(shell.err, "ambiguous cd: $home empty\n"); + } + break; + + case 1: + // TODO: add cdpath + cdpath = &nullpath; + for(; cdpath; cdpath = cdpath->link){ + strcpy(dir, cdpath->str); + if(dir[0]) + strcat(dir,"/"); + strcat(dir, arg->str); + if(chdir(dir) < 0){ + print(shell.err, "failed cd %s: %s\n", dir, strerror(errno)); + } + break; + } + break; + } + + poplist(); +} + static Code dotcmd[14] = { [0] = {.i = 0}, @@ -440,49 +537,6 @@ xdot(void) } void -xcd(void) -{ - Word *arg; - Word *cdpath; - char dir[512]; - - popword(); // cd - - arg = runner->args->word; - switch(count(arg)){ - default: - print(shell.err, "usage: cd [directory]\n"); - break; - case 0: - arg = var("home")->val; - if(count(arg) >= 1){ - if(chdir(arg->str) < 0) - print(shell.err, "failed cd: %s\n", strerror(errno)); - }else{ - print(shell.err, "ambiguous cd: $home empty\n"); - } - break; - - case 1: - // TODO: add cdpath - cdpath = &nullpath; - for(; cdpath; cdpath = cdpath->link){ - strcpy(dir, cdpath->str); - if(dir[0]) - strcat(dir,"/"); - strcat(dir, arg->str); - if(chdir(dir) < 0){ - print(shell.err, "failed cd %s: %s\n", dir, strerror(errno)); - } - break; - } - break; - } - - poplist(); -} - -void xjob(void) { int i; @@ -581,18 +635,24 @@ Xword(void) void Xtrue(void) { - if(!runner->status) + if(!runner->status){ + assert(runner->wait.status == Pdone); runner->code.i++; - else + deljob(runner); + runner->pgid = -1; + }else runner->code.i = runner->code.exe[runner->code.i].i; } void Xfalse(void) { - if(runner->status) + if(runner->status){ + assert(runner->wait.status == Pdone); runner->code.i++; - else + deljob(runner); + runner->pgid = -1; + } else runner->code.i = runner->code.exe[runner->code.i].i; } @@ -956,8 +1016,8 @@ Xbasic(void) return; } - foreground(runner, 0); // waits for child poplist(); + foreground(runner, 0); // waits for child } void diff --git a/sys/cmd/rc/exec.h b/sys/cmd/rc/exec.h index 652edea..9edd9ed 100644 --- a/sys/cmd/rc/exec.h +++ b/sys/cmd/rc/exec.h @@ -34,7 +34,10 @@ void Xerror(char*); /* builtin commands */ void xcd(void); -void xfg(void); void xdot(void); +void xecho(void); +void xexit(void); +void xfg(void); void xjob(void); + void xboot(int argc, char *argv[]); diff --git a/sys/cmd/rc/prompt.c b/sys/cmd/rc/prompt.c index 7635bd8..e3ff7d9 100644 --- a/sys/cmd/rc/prompt.c +++ b/sys/cmd/rc/prompt.c @@ -9,7 +9,7 @@ prompt(ushort *flag) runner->flag.eof = 1; return 0; } - print(shell.err, "\n"); + print(shell.err,"\n\r"); flush(shell.err); runner->line++; *flag = 0; diff --git a/sys/cmd/rc/rc.h b/sys/cmd/rc/rc.h index 13444e6..85a046a 100644 --- a/sys/cmd/rc/rc.h +++ b/sys/cmd/rc/rc.h @@ -211,6 +211,7 @@ void freeparsetree(void); void initenv(void); void redirect(struct Redir *); void execute(Word *, Word*); +int mapfd(int fd); /* wait.c */ void addwait(Thread *, int); |