commit bc84292076945924cd9b006c061ae04d79f4209f
parent a32879322714f53ec044dabe4d20c44cb85be116
Author: Toby Goodwin <toby@paccrat.org>
Date: Fri, 16 Mar 2018 20:20:46 +0000
starting to work
Diffstat:
M | builtins.c | | | 265 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
M | main.c | | | 3 | ++- |
M | rc.h | | | 1 | + |
3 files changed, 159 insertions(+), 110 deletions(-)
diff --git a/builtins.c b/builtins.c
@@ -21,8 +21,8 @@
#include "sigmsgs.h"
static void b_break(char **), b_cd(char **), b_eval(char **), b_exit(char **),
- b_newpgrp(char **), b_return(char **), b_shift(char **), b_umask(char **),
- b_wait(char **), b_whatis(char **);
+ b_flag(char **), b_newpgrp(char **), b_return(char **),
+ b_shift(char **), b_umask(char **), b_wait(char **), b_whatis(char **);
#if HAVE_SETRLIMIT
static void b_limit(char **);
@@ -45,56 +45,57 @@ static struct {
{ b_eval, "eval" },
{ b_exec, "exec" },
{ b_exit, "exit" },
+ { b_flag, "flag" },
#if HAVE_SETRLIMIT
- { b_limit, "limit" },
+ { b_limit, "limit" },
#endif
- { b_newpgrp, "newpgrp" },
- { b_return, "return" },
- { b_shift, "shift" },
- { b_umask, "umask" },
- { b_wait, "wait" },
- { b_whatis, "whatis" },
- { b_dot, "." },
+ { b_newpgrp, "newpgrp" },
+ { b_return, "return" },
+ { b_shift, "shift" },
+ { b_umask, "umask" },
+ { b_wait, "wait" },
+ { b_whatis, "whatis" },
+ { b_dot, "." },
#ifdef ADDONS
- ADDONS
+ ADDONS
#endif
};
extern builtin_t *isbuiltin(char *s) {
- int i;
- for (i = 0; i < arraysize(builtins); i++)
- if (streq(builtins[i].name, s))
- return builtins[i].p;
- return NULL;
+ int i;
+ for (i = 0; i < arraysize(builtins); i++)
+ if (streq(builtins[i].name, s))
+ return builtins[i].p;
+ return NULL;
}
/* funcall() is the wrapper used to invoke shell functions. pushes $*, and "return" returns here. */
extern void funcall(char **av) {
- Jbwrap j;
- Estack e1, e2;
- Edata jreturn, star;
- if (sigsetjmp(j.j, 1))
- return;
- starassign(*av, av+1, TRUE);
- jreturn.jb = &j;
- star.name = "*";
- except(eReturn, jreturn, &e1);
- except(eVarstack, star, &e2);
- walk(treecpy(fnlookup(*av), nalloc), TRUE);
- varrm("*", TRUE);
- unexcept(); /* eVarstack */
- unexcept(); /* eReturn */
+ Jbwrap j;
+ Estack e1, e2;
+ Edata jreturn, star;
+ if (sigsetjmp(j.j, 1))
+ return;
+ starassign(*av, av+1, TRUE);
+ jreturn.jb = &j;
+ star.name = "*";
+ except(eReturn, jreturn, &e1);
+ except(eVarstack, star, &e2);
+ walk(treecpy(fnlookup(*av), nalloc), TRUE);
+ varrm("*", TRUE);
+ unexcept(); /* eVarstack */
+ unexcept(); /* eReturn */
}
static void arg_count(char *name) {
- fprint(2, RC "too many arguments to %s\n", name);
- set(FALSE);
+ fprint(2, RC "too many arguments to %s\n", name);
+ set(FALSE);
}
static void badnum(char *num) {
- fprint(2, RC "`%s' is a bad number\n", num);
- set(FALSE);
+ fprint(2, RC "`%s' is a bad number\n", num);
+ set(FALSE);
}
/* a dummy command. (exec() performs "exec" simply by not forking) */
@@ -106,90 +107,90 @@ extern void b_exec(char **ignore) {
/* echo -n omits a newline. echo -- -n echos '-n' */
static void b_echo(char **av) {
- char *format = "%A\n";
- if (*++av != NULL) {
- if (streq(*av, "-n"))
- format = "%A", av++;
- else if (streq(*av, "--"))
- av++;
- }
- fprint(1, format, av);
- set(TRUE);
+ char *format = "%A\n";
+ if (*++av != NULL) {
+ if (streq(*av, "-n"))
+ format = "%A", av++;
+ else if (streq(*av, "--"))
+ av++;
+ }
+ fprint(1, format, av);
+ set(TRUE);
}
#endif
/* cd. traverse $cdpath if the directory given is not an absolute pathname */
static void b_cd(char **av) {
- List *s, nil;
- char *path = NULL;
- size_t t, pathlen = 0;
- if (*++av == NULL) {
- s = varlookup("home");
- *av = (s == NULL) ? "/" : s->w;
- } else if (av[1] != NULL) {
- arg_count("cd");
- return;
- }
- if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */
- if (chdir(*av) < 0) {
- set(FALSE);
- uerror(*av);
- } else
- set(TRUE);
- } else {
- s = varlookup("cdpath");
- if (s == NULL) {
- s = &nil;
- nil.w = "";
- nil.n = NULL;
- }
- do {
- if (s != &nil && *s->w != '\0') {
- t = strlen(*av) + strlen(s->w) + 2;
- if (t > pathlen)
- path = nalloc(pathlen = t);
- strcpy(path, s->w);
- if (!streq(s->w, "/")) /* "//" is special to POSIX */
- strcat(path, "/");
- strcat(path, *av);
- } else {
- pathlen = 0;
- path = *av;
- }
- if (chdir(path) >= 0) {
- set(TRUE);
- if (interactive && *s->w != '\0' && !streq(s->w, "."))
- fprint(1, "%s\n", path);
- return;
- }
- s = s->n;
- } while (s != NULL);
- fprint(2, "couldn't cd to %s\n", *av);
- set(FALSE);
- }
+ List *s, nil;
+ char *path = NULL;
+ size_t t, pathlen = 0;
+ if (*++av == NULL) {
+ s = varlookup("home");
+ *av = (s == NULL) ? "/" : s->w;
+ } else if (av[1] != NULL) {
+ arg_count("cd");
+ return;
+ }
+ if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */
+ if (chdir(*av) < 0) {
+ set(FALSE);
+ uerror(*av);
+ } else
+ set(TRUE);
+ } else {
+ s = varlookup("cdpath");
+ if (s == NULL) {
+ s = &nil;
+ nil.w = "";
+ nil.n = NULL;
+ }
+ do {
+ if (s != &nil && *s->w != '\0') {
+ t = strlen(*av) + strlen(s->w) + 2;
+ if (t > pathlen)
+ path = nalloc(pathlen = t);
+ strcpy(path, s->w);
+ if (!streq(s->w, "/")) /* "//" is special to POSIX */
+ strcat(path, "/");
+ strcat(path, *av);
+ } else {
+ pathlen = 0;
+ path = *av;
+ }
+ if (chdir(path) >= 0) {
+ set(TRUE);
+ if (interactive && *s->w != '\0' && !streq(s->w, "."))
+ fprint(1, "%s\n", path);
+ return;
+ }
+ s = s->n;
+ } while (s != NULL);
+ fprint(2, "couldn't cd to %s\n", *av);
+ set(FALSE);
+ }
}
static void b_umask(char **av) {
- int i;
- if (*++av == NULL) {
- set(TRUE);
- i = umask(0);
- umask(i);
- fprint(1, "0%o\n", i);
- } else if (av[1] == NULL) {
- i = o2u(*av);
- if ((unsigned int) i > 0777) {
- fprint(2, "bad umask\n");
- set(FALSE);
- } else {
- umask(i);
- set(TRUE);
- }
- } else {
- arg_count("umask");
- return;
- }
+ int i;
+ if (*++av == NULL) {
+ set(TRUE);
+ i = umask(0);
+ umask(i);
+ fprint(1, "0%o\n", i);
+ } else if (av[1] == NULL) {
+ i = o2u(*av);
+ if ((unsigned int) i > 0777) {
+ fprint(2, "bad umask\n");
+ set(FALSE);
+ } else {
+ umask(i);
+ set(TRUE);
+ }
+ } else {
+ arg_count("umask");
+ return;
+ }
}
static void b_exit(char **av) {
@@ -198,6 +199,52 @@ static void b_exit(char **av) {
rc_exit(getstatus());
}
+static void b_flag(char **av) {
+ bool *flagp = NULL;
+ char f;
+ int mode = 3; /* 0 = reset (-), 1 = set (+), 2 = test */
+ const char *usage = "usage: flag f [ + | - ]\n";
+
+ if (*++av == NULL) {
+ fprint(2, RC "not enough arguments to flag\n");
+ set(FALSE);
+ return;
+ }
+ f = av[0][0];
+ if (av[0][1] != '\0') {
+ fprint(2, usage);
+ set(FALSE);
+ return;
+ }
+ if (*++av == NULL) {
+ mode = 2;
+ } else if (av[0][0] == '+' && av[0][1] == '\0') {
+ mode = 1;
+ } else if (av[0][0] == '-' && av[0][1] == '\0') {
+ mode = 0;
+ }
+ if (mode == 3) {
+ fprint(2, usage);
+ set(FALSE);
+ return;
+ }
+ switch (f) {
+ case 'c':
+ if (mode == 2) {
+ set(dashsee[0] != NULL);
+ return;
+ } else {
+ fprint(2, RC "flag immutable\n");
+ set(FALSE);
+ return;
+ }
+
+
+ case 'e': flagp = &dashee; break;
+ }
+ set(FALSE);
+}
+
/* raise a "return" exception, i.e., return from a function. if an integer argument is present, set $status to it */
static void b_return(char **av) {
diff --git a/main.c b/main.c
@@ -8,6 +8,7 @@
bool dashdee, dashee, dashvee, dashex, dasheye,
dashen, dashpee, interactive;
+char *dashsee[2];
pid_t rc_pid;
static bool dashEYE, dashell, dashoh, dashess;
@@ -16,7 +17,7 @@ static void assigndefault(char *,...);
static void checkfd(int, enum redirtype);
extern int main(int argc, char *argv[], char *envp[]) {
- char *dashsee[2], *dollarzero, *null[1];
+ char *dollarzero, *null[1];
int c;
initprint();
dashsee[0] = dashsee[1] = NULL;
diff --git a/rc.h b/rc.h
@@ -171,6 +171,7 @@ enum {
/* main.c */
extern Rq *redirq;
extern bool dashdee, dashee, dashvee, dashex, dasheye, dashen, dashpee, interactive;
+extern char *dashsee[];
extern pid_t rc_pid;
extern int lineno;