From 3733507b090311b70ca8a2fed0c739b808f679c6 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 21 Oct 2021 16:53:23 -0700 Subject: feat(rc): added a few builtins --- sys/cmd/rc/exec.c | 158 ++++++++++++++++++++++++++++++++++++---------------- sys/cmd/rc/exec.h | 5 +- sys/cmd/rc/prompt.c | 2 +- sys/cmd/rc/rc.h | 1 + 4 files changed, 115 insertions(+), 51 deletions(-) (limited to 'sys/cmd') 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}, @@ -439,49 +536,6 @@ xdot(void) //ndot++; } -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) { @@ -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); -- cgit v1.2.1