aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-21 16:53:23 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-21 16:53:23 -0700
commit3733507b090311b70ca8a2fed0c739b808f679c6 (patch)
treea964964480489b1a274a1bf1ec208243ccdf70d0
parentda77d3be2eb0785bc0c0b60c686e163d6243c744 (diff)
feat(rc): added a few builtins
-rw-r--r--sys/cmd/rc/exec.c158
-rw-r--r--sys/cmd/rc/exec.h5
-rw-r--r--sys/cmd/rc/prompt.c2
-rw-r--r--sys/cmd/rc/rc.h1
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);