diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2021-10-09 10:30:50 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2021-10-09 10:30:50 -0700 |
commit | 6f2cac23a7e759c464ef52103fac929e1eeb6b10 (patch) | |
tree | d2412c7f82fc47bdb6dc47d82b685982e63cefe7 /sys/cmd/rc/exec.c | |
parent | 80f92a7109c0bce2f4220ff1ce04ec8fd6fb9f8c (diff) |
feat(rc): added shell
Diffstat (limited to 'sys/cmd/rc/exec.c')
-rw-r--r-- | sys/cmd/rc/exec.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c new file mode 100644 index 0000000..0155b22 --- /dev/null +++ b/sys/cmd/rc/exec.c @@ -0,0 +1,139 @@ +#include "rc.h" + +#define W0 shell->stack->words +// ----------------------------------------------------------------------- +// helper functions + +static +void +setstatus(char *s) +{ + setvar("status", newword(s, nil)); +} + +static +void +pushredir(int type, int from, int to) +{ + Redir *r; + + alloc(r); + r->type = type; + r->from = from; + r->to = to; + r->link = shell->redir, shell->redir = r; +} + +// ----------------------------------------------------------------------- +// interpreter functions + +void +Xerror(char *s) +{ + if(!strcmp(argv0, "rc")||!strcmp(argv0, "/bin/rc")) + pfmt(errio, "rc: %s: %r\n", s); + else + pfmt(errio, "rc (%s): %s: %r\n", argv0, s); + flush(&errio); + + setstatus("error"); + while(!shell->interactive) + Xkill(); +} + +void +Xappend(void) +{ + int fd; + char *path; + + switch(count(W0)) { + default: + Xerror(">> requires a singleton list"); + return; + case 0: + Xerror(">> requires one file"); + return; + case 1: + ; + } + + path = shell->stack->words->word; + if ((fd=open(path, 1))< 0 && (fd=creat(path, 0666L))<0) { + pfmt(errio, "%s: ", path); + Xerror("can't open"); + return; + } + lseek(fd, 0L, 2); + pushredir(Fopen, fd, shell->ip++->i); + poplist(); +} + +void +Xassign(void) +{ + Var *v; + if(count(W0)!=1) { + Xerror("variable name not singleton"); + return; + } + unglob(W0->word); + v = vlookup(W0->word); + poplist(); + globlist(); + freelist(v->val); + + v->val = W0; + if(v->update) + v->update(v); + W0 = nil; + poplist(); +} + +void +Xmark(void) +{ + pushlist(); +} + +void +Xword(void) +{ + pushword(shell->ip++->s); +} + +void Xasync(void); +void Xcat(void); +void Xclose(void); +void Xcmdsub(void); +void Xcount(void); +void Xdol(void); +void Xdup(void); +void Xexit(void); +void Xfalse(void); +void Xflatten(void); +void Xfor(void); +void Xfunc(void); +void Xglob(void); +void Xif(void); +void Xjump(void); +void Xkill(void); +void Xlocal(void); +void Xmark(void); +void Xmatch(void); +void Xnegate(void); +void Xpipe(void); +void Xpipefd(void); +void Xpipewait(void); +void Xpop(void); +void Xpopredir(void); +void Xrdwr(void); +void Xread(void); +void Xsub(void); +void Xsimple(void); +void Xsubshell(void); +void Xtrue(void); +void Xunfunc(void); +void Xunlocal(void); +void Xword(void); +void Xwrite(void); |