aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/exec.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-09 10:30:50 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-09 10:30:50 -0700
commit6f2cac23a7e759c464ef52103fac929e1eeb6b10 (patch)
treed2412c7f82fc47bdb6dc47d82b685982e63cefe7 /sys/cmd/rc/exec.c
parent80f92a7109c0bce2f4220ff1ce04ec8fd6fb9f8c (diff)
feat(rc): added shell
Diffstat (limited to 'sys/cmd/rc/exec.c')
-rw-r--r--sys/cmd/rc/exec.c139
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);