From ab400c0be5577cab2a66d242183887ebbd61717f Mon Sep 17 00:00:00 2001 From: Nicholas Date: Wed, 17 Nov 2021 08:22:03 -0800 Subject: checkin --- src/cmd/rc/exec.c | 74 +++++++++++++++++++++++++---------------------------- src/cmd/rc/exec.h | 2 +- src/cmd/rc/lex.c | 17 +++++++++--- src/cmd/rc/main.c | 42 ++++++++++++++++++++++++------ src/cmd/rc/prompt.c | 7 ++--- src/cmd/rc/rc.h | 8 ++++-- src/cmd/rc/rules.mk | 2 +- src/cmd/rc/var.c | 30 +++++++--------------- 8 files changed, 101 insertions(+), 81 deletions(-) (limited to 'src/cmd/rc') diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c index 51e352a..bd68bf5 100644 --- a/src/cmd/rc/exec.c +++ b/src/cmd/rc/exec.c @@ -36,8 +36,7 @@ struct Builtin builtin[]={ /* words and lists */ -static -void +static void pushword(char *str) { if(!runner->args) @@ -46,8 +45,7 @@ pushword(char *str) runner->args->word = makeword(str, runner->args->word); } -static -void +static void popword(void) { Word *w; @@ -63,8 +61,7 @@ popword(void) efree(w); } -static -Word* +static Word* copywords(Word *a, Word *tail) { Word *v = nil, **end; @@ -76,8 +73,7 @@ copywords(Word *a, Word *tail) return v; } -static -void +static void freewords(Word *w) { Word *n; @@ -89,8 +85,7 @@ freewords(Word *w) } } -static -void +static void freelist(Word *w) { Word *n; @@ -100,7 +95,6 @@ freelist(Word *w) efree(w); w = n; } - } static void @@ -154,7 +148,7 @@ path(char *w) if(strncmp(w, "/", 1)==0 || strncmp(w, "./", 2)==0 || strncmp(w, "../", 3)==0 - || (path = var("path")->val)==0) + || !(path = var("path")->val)) path=&nullpath; return path; @@ -262,7 +256,7 @@ xforkx(void) initchild(runner, 1); pushword("exec"); xx(); - exit(2); // reach here on failed execs + exit(errno); // reach here on failed execs break; default: // parent initparent(runner, pid, 0); @@ -505,7 +499,7 @@ xcd(void) static Code dotcmd[14] = { - [0] = {.i = 0}, + [0] = {.i = 1}, // offset by 1 to ensure it never gets freed [1] = {.f = Xmark}, [2] = {.f = Xword}, [3] = {.s = "0"}, @@ -557,7 +551,7 @@ xdot(void) } if(fd<0){ - print(shell.err, "failed open: %s: ", base); + print(shell.err, "%s: ", base); setstatus("failed open"); Xerror(".: failed open"); return; @@ -626,41 +620,43 @@ xfg(void) foreground(job, 1); } +static Code bootstrap[32] = +{ + [0] = {.i = 1}, + [1] = {.f = Xmark}, + [2] = {.f = Xword}, + [3] = {.s = "*"}, + [4] = {.f = Xassign}, + [5] = {.f = Xmark}, + [6] = {.f = Xmark}, + [7] = {.f = Xword}, + [8] = {.s = "*"}, + [9] = {.f = Xdollar}, + [10] = {.f = Xword}, + [11] = {.s = nil}, /* XXX: to be filled in by caller */ + [12] = {.f = Xword}, + [13] = {.s = "."}, + [14] = {.f = Xbasic}, + [15] = {.f = Xexit}, + [16] = {.i = 0} +}; + void -xboot(int argc, char *argv[]) +xboot(char *exe, int argc, char *argv[]) { int i; - Code bootstrap[32]; char num[12]; - i = 0; - bootstrap[i++].i = 1; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xword; - bootstrap[i++].s="*"; - bootstrap[i++].f = Xassign; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xword; - bootstrap[i++].s="*"; - bootstrap[i++].f = Xdollar; - bootstrap[i++].f = Xword; - bootstrap[i++].s = "./cmds"; /* /dev/stdin"; */ - bootstrap[i++].f = Xword; - bootstrap[i++].s="."; - bootstrap[i++].f = Xbasic; - bootstrap[i++].f = Xexit; - bootstrap[i].i = 0; - + bootstrap[11].s = exe; run(bootstrap, 1, nil, 0); runner->pid = runner->pgid = shell.pid; pushlist(); // prime bootstrap argv - argv0 = strdup(argv[0]); - for(i = argc-1; i > 0; --i) + /* initialize $* */ + for(i = argc-1; i >= 0; --i) pushword(argv[i]); - /* main interpreter loop */ + /* main loop */ for(;;){ runner->code.i++; (*runner->code.exe[runner->code.i-1].f)(); diff --git a/src/cmd/rc/exec.h b/src/cmd/rc/exec.h index 992af35..28cbd80 100644 --- a/src/cmd/rc/exec.h +++ b/src/cmd/rc/exec.h @@ -60,4 +60,4 @@ void xfg(void); void xjob(void); void xfunc(Var *v); -void xboot(int argc, char *argv[]); +void xboot(char *exe, int argc, char *argv[]); diff --git a/src/cmd/rc/lex.c b/src/cmd/rc/lex.c index 9283404..f2c0a60 100644 --- a/src/cmd/rc/lex.c +++ b/src/cmd/rc/lex.c @@ -147,8 +147,11 @@ readc(void) if(runner->flag.eof) return EOF; - if(!prompt(&lexer.doprompt)) - exit(1); // XXX: hack for signal handling right now... + if(lexer.doprompt){ + if(!prompt()) + exit(1); // XXX: hack for signal handling right now... + lexer.doprompt = 0; + } c = get(runner->cmd.io); lexer.doprompt = lexer.doprompt || c=='\n' || c==EOF; @@ -290,7 +293,7 @@ readhere(void) yyerror("failed to make heredoc"); io = openfd(c); - prompt(&lexer.doprompt); + prompt(); beg=line, s=line, end=arrend(line)-1, len=PAGESIZE; while((c=get(runner->cmd.io))!=EOF){ @@ -318,7 +321,7 @@ readhere(void) printstr(io, beg); /* reset */ s = beg; - prompt(&lexer.doprompt); + prompt(); printchar(io, c); } @@ -351,6 +354,12 @@ isidentchar(int c) return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); } +void +initlexer(int f) +{ + lexer.doprompt=f; +} + int yylex(void) { diff --git a/src/cmd/rc/main.c b/src/cmd/rc/main.c index 81c7b8c..337470a 100644 --- a/src/cmd/rc/main.c +++ b/src/cmd/rc/main.c @@ -15,9 +15,9 @@ Shell shell = { 0 }; // functions void -initshell(void) +initshell(int *iflag) { - if((shell.interactive=0)){ //isatty(0))){ + if((*iflag=isatty(0))){ while(tcgetpgrp(0) != (shell.pid = getpgrp())) kill(-shell.pid, SIGTTIN); @@ -27,8 +27,7 @@ initshell(void) signal(SIGTSTP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); - /* - * NOTE: if SIGCHLD is set to SIG_IGN then + /* NOTE: if SIGCHLD is set to SIG_IGN then * 1. children that terminate do not become zombies * 2. call a to wait() will block until all children have terminated * 3. the call to wait will fail with errno == ECHILD @@ -49,20 +48,47 @@ initshell(void) // ----------------------------------------------------------------------- // main point of entry +static void +usage(void) +{ + print(shell.err, "usage: %s [-cei] [file]", argv0); + exit(2); +} + int main(int argc, char *argv[]) { + int flag; + char *exe, *cmd = nil; shell.err = openfd(2); - /* yydebug=1; */ - initenv(); initpath(); initkeywords(); - initshell(); inithistory(); + initshell(&flag); + + ARGBEGIN{ + case 'e': shell.noerror = 1; break; + case 'i': shell.interactive = 1; break; + case 'I': shell.interactive = 0; break; + case 'c': + cmd = EARGF(usage()); + panicf("not implemented"); + break; + default: + usage(); + }ARGEND; + + if(!argc){ + shell.interactive |= flag; + exe = "/dev/stdin"; + }else + exe = *argv++, argc--; + + initlexer(shell.interactive); /* enablevi(); */ - xboot(argc, argv); + xboot(exe, argc, argv); /* unreachable */ } diff --git a/src/cmd/rc/prompt.c b/src/cmd/rc/prompt.c index 1122d54..5579b0d 100644 --- a/src/cmd/rc/prompt.c +++ b/src/cmd/rc/prompt.c @@ -10,11 +10,9 @@ resetprompt(void) } int -prompt(ushort *flag) +prompt(void) { - int f = *flag; - - if(f){ + if(runner->flag.user){ if(!readline(promptstr)){ runner->flag.eof = 1; return 0; @@ -29,7 +27,6 @@ prompt(ushort *flag) promptstr = " "; runner->line++; - *flag = 0; } return 1; diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h index f5c8a6d..f52e4e2 100644 --- a/src/cmd/rc/rc.h +++ b/src/cmd/rc/rc.h @@ -157,7 +157,10 @@ struct Shell int pid; Io *err; int status; - int interactive; + struct{ + int interactive; + int noerror; + }; /* flags */ Thread *jobs; }; @@ -187,7 +190,7 @@ int addhistory(char *); /* prompt.c */ void resetprompt(void); -int prompt(ushort *); +int prompt(void); /* io.c */ Io *openfd(int fd); @@ -205,6 +208,7 @@ void printchar(Io *, int); /* lex.c */ int yylex(void); void yyerror(const char *msg); +void initlexer(int); void readhere(void); Tree *heredoc(Tree *); diff --git a/src/cmd/rc/rules.mk b/src/cmd/rc/rules.mk index 206c517..0758439 100644 --- a/src/cmd/rc/rules.mk +++ b/src/cmd/rc/rules.mk @@ -24,7 +24,7 @@ BINS_$(d) := $(d)/rc include share/paths.mk $(d)/parse.h $(d)/parse.c: $(d)/syntax.y - bison --debug --defines=$(update(v); } -static -char* +static char* list2strcolon(Word *words) { char *value, *s, *t; @@ -70,8 +67,7 @@ list2strcolon(Word *words) return value; } -static -void +static void littlepath(Var *v) { /* convert $path to $PATH */ @@ -86,8 +82,7 @@ littlepath(Var *v) ·setvar("PATH", w, 1); } -static -void +static void bigpath(Var *v) { /* convert $PATH to $path */ @@ -103,7 +98,7 @@ bigpath(Var *v) w = nil; l = &w; - /* Doesn't handle escaped colon nonsense. */ + /* we don't handle escaped colons */ if(p[0] == 0) p = nil; @@ -195,13 +190,6 @@ var(char *name) return globalvar(name); } -static -int -cmpenv(const void *a, const void *b) -{ - return strcmp(*(char**)a, *(char**)b); -} - char** mkenv(void) { @@ -218,7 +206,7 @@ mkenv(void) nchr+=strlen(a->str)+1; \ } - for(v= runner->local; v; v=v->link){ + for(v = runner->local; v; v=v->link){ BODY } for(h=globals; h!=arrend(globals); h++){ @@ -262,8 +250,8 @@ mkenv(void) *ep=0; - qsort((char *)env, nvar, sizeof ep[0], cmpenv); - return env; + sort·string(nvar, env); + return env; } void -- cgit v1.2.1