rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit bc84292076945924cd9b006c061ae04d79f4209f
parent a32879322714f53ec044dabe4d20c44cb85be116
Author: Toby Goodwin <toby@paccrat.org>
Date:   Fri, 16 Mar 2018 20:20:46 +0000

starting to work

Diffstat:
Mbuiltins.c | 265++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mmain.c | 3++-
Mrc.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;