From 085f5dfa349a7fa964f613bc0694536d5b79c7ac Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Wed, 18 Oct 2017 01:10:06 +0200 Subject: [PATCH] rc: import 9front's improvements --- sys/src/cmd/rc/code.c | 103 +++--- sys/src/cmd/rc/exec.c | 185 +++++------ sys/src/cmd/rc/exec.h | 4 +- sys/src/cmd/rc/fns.h | 18 +- sys/src/cmd/rc/glob.c | 179 +++++------ sys/src/cmd/rc/havefork.c | 65 ++-- sys/src/cmd/rc/haventfork.c | 220 ------------- sys/src/cmd/rc/here.c | 55 ++-- sys/src/cmd/rc/io.c | 41 +-- sys/src/cmd/rc/io.h | 1 - sys/src/cmd/rc/lex.c | 14 +- sys/src/cmd/rc/pcmd.c | 3 +- sys/src/cmd/rc/pfnc.c | 63 ++-- sys/src/cmd/rc/plan9.c | 167 +++------- sys/src/cmd/rc/rc.h | 43 +-- sys/src/cmd/rc/rcmain.unix | 34 -- sys/src/cmd/rc/run.unix | 20 -- sys/src/cmd/rc/simple.c | 97 ++---- sys/src/cmd/rc/subr.c | 33 +- sys/src/cmd/rc/syn.y | 3 +- sys/src/cmd/rc/trap.c | 2 +- sys/src/cmd/rc/tree.c | 10 +- sys/src/cmd/rc/unix.c | 601 ------------------------------------ sys/src/cmd/rc/unix.h | 62 ---- sys/src/cmd/rc/var.c | 21 +- sys/src/cmd/rc/win32.c | 570 ---------------------------------- 26 files changed, 481 insertions(+), 2133 deletions(-) delete mode 100644 sys/src/cmd/rc/haventfork.c delete mode 100755 sys/src/cmd/rc/rcmain.unix delete mode 100755 sys/src/cmd/rc/run.unix delete mode 100644 sys/src/cmd/rc/unix.c delete mode 100644 sys/src/cmd/rc/unix.h delete mode 100644 sys/src/cmd/rc/win32.c diff --git a/sys/src/cmd/rc/code.c b/sys/src/cmd/rc/code.c index 818dccb..07d1f7c 100644 --- a/sys/src/cmd/rc/code.c +++ b/sys/src/cmd/rc/code.c @@ -31,10 +31,7 @@ int morecode(void) { ncode+=100; - codebuf = (code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]); - if(codebuf==0) - panic("Can't realloc %d bytes in morecode!", - ncode*sizeof codebuf[0]); + codebuf = (code *)erealloc((char *)codebuf, ncode*sizeof codebuf[0]); return 0; } @@ -55,7 +52,7 @@ compile(tree *t) emiti(0); /* reference count */ outcode(t, flag['e']?1:0); if(nerror){ - efree((char *)codebuf); + free(codebuf); return 0; } readhere(); @@ -68,7 +65,7 @@ void cleanhere(char *f) { emitf(Xdelhere); - emits(strdup(f)); + emits(estrdup(f)); } char* @@ -120,13 +117,10 @@ outcode(tree *t, int eflag) break; case '&': emitf(Xasync); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); + p = emiti(0); + outcode(c0, eflag); + emitf(Xexit); + stuffdot(p); break; case ';': outcode(c0, eflag); @@ -140,14 +134,21 @@ outcode(tree *t, int eflag) emitf(Xconc); break; case '`': - emitf(Xbackq); - if(havefork){ - p = emiti(0); + emitf(Xmark); + if(c0){ outcode(c0, 0); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); + emitf(Xglob); + } else { + emitf(Xmark); + emitf(Xword); + emits(estrdup("ifs")); + emitf(Xdol); + } + emitf(Xbackq); + p = emiti(0); + outcode(c1, 0); + emitf(Xexit); + stuffdot(p); break; case ANDAND: outcode(c0, 0); @@ -223,13 +224,10 @@ outcode(tree *t, int eflag) break; case SUBSHELL: emitf(Xsubshell); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); + p = emiti(0); + outcode(c0, eflag); + emitf(Xexit); + stuffdot(p); if(eflag) emitf(Xeflag); break; @@ -270,7 +268,7 @@ outcode(tree *t, int eflag) else{ emitf(Xmark); emitf(Xword); - emits(strdup("*")); + emits(estrdup("*")); emitf(Xdol); } emitf(Xmark); /* dummy value for Xlocal */ @@ -286,8 +284,19 @@ outcode(tree *t, int eflag) emitf(Xunlocal); break; case WORD: - emitf(Xword); - emits(strdup(t->str)); + if(t->quoted){ + emitf(Xword); + emits(estrdup(t->str)); + } else { + if((q = Globsize(t->str)) > 0){ + emitf(Xglobs); + emits(estrdup(t->str)); + emiti(q); + } else { + emitf(Xword); + emits(deglob(estrdup(t->str))); + } + } break; case DUP: if(t->rtype==DUPFD){ @@ -305,14 +314,10 @@ outcode(tree *t, int eflag) case PIPEFD: emitf(Xpipefd); emiti(t->rtype); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else { - emits(fnstr(c0)); - } + p = emiti(0); + outcode(c0, eflag); + emitf(Xexit); + stuffdot(p); break; case REDIR: emitf(Xmark); @@ -367,16 +372,11 @@ outcode(tree *t, int eflag) emitf(Xpipe); emiti(t->fd0); emiti(t->fd1); - if(havefork){ - p = emiti(0); - q = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else { - emits(fnstr(c0)); - q = emiti(0); - } + p = emiti(0); + q = emiti(0); + outcode(c0, eflag); + emitf(Xexit); + stuffdot(p); outcode(c1, eflag); emitf(Xreturn); stuffdot(q); @@ -485,11 +485,12 @@ codefree(code *cp) || p->f==Xsubshell || p->f==Xtrue) p++; else if(p->f==Xdup || p->f==Xpipefd) p+=2; else if(p->f==Xpipe) p+=4; - else if(p->f==Xword || p->f==Xdelhere) efree((++p)->s); + else if(p->f==Xglobs) free(p[1].s), p+=2; + else if(p->f==Xword || p->f==Xdelhere) free((++p)->s); else if(p->f==Xfn){ - efree(p[2].s); + free(p[2].s); p+=2; } } - efree((char *)cp); + free(cp); } diff --git a/sys/src/cmd/rc/exec.c b/sys/src/cmd/rc/exec.c index 5ff4494..9afc894 100644 --- a/sys/src/cmd/rc/exec.c +++ b/sys/src/cmd/rc/exec.c @@ -37,20 +37,34 @@ start(code *c, int pc, var *local) } word* -newword(char *wd, word *next) +Newword(char *wd, word *next) { word *p = new(word); - p->word = strdup(wd); + p->word = wd; p->next = next; + p->glob = 0; return p; } - -void -pushword(char *wd) +word* +Pushword(char *wd) { + word *w; if(runq->argv==0) panic("pushword but no argv!", 0); - runq->argv->words = newword(wd, runq->argv->words); + w = Newword(wd, runq->argv->words); + runq->argv->words = w; + return w; +} + +word* +newword(char *wd, word *next) +{ + return Newword(estrdup(wd), next); +} +word* +pushword(char *wd) +{ + return Pushword(estrdup(wd)); } void @@ -63,8 +77,8 @@ popword(void) if(p==0) panic("popword but no word!", 0); runq->argv->words = p->next; - efree(p->word); - efree((char *)p); + free(p->word); + free(p); } void @@ -73,8 +87,8 @@ freelist(word *w) word *nw; while(w){ nw = w->next; - efree(w->word); - efree((char *)w); + free(w->word); + free(w); w = nw; } } @@ -96,7 +110,7 @@ poplist(void) panic("poplist but no argv", 0); freelist(p->words); runq->argv = p->next; - efree((char *)p); + free(p); } int @@ -122,7 +136,7 @@ var* newvar(char *name, var *next) { var *v = new(var); - v->name = name; + v->name = estrdup(name); v->val = 0; v->fn = 0; v->changed = 0; @@ -166,7 +180,6 @@ main(int argc, char *argv[]) :(word *)0); setvar("rcname", newword(argv[0], (word *)0)); i = 0; - memset(bootstrap, 0, sizeof bootstrap); bootstrap[i++].i = 1; bootstrap[i++].f = Xmark; bootstrap[i++].f = Xword; @@ -187,8 +200,9 @@ main(int argc, char *argv[]) start(bootstrap, 1, (var *)0); /* prime bootstrap argv */ pushlist(); - argv0 = strdup(argv[0]); - for(i = argc-1;i!=0;--i) pushword(argv[i]); + argv0 = estrdup(argvcopy[0]); + for(i = argc-1; i != 0; --i) + pushword(argv[i]); for(;;){ if(flag['r']) pfnc(err, runq); @@ -207,7 +221,7 @@ main(int argc, char *argv[]) * Xappend(file)[fd] open file to append * Xassign(name, val) assign val to name * Xasync{... Xexit} make thread for {}, no wait - * Xbackq{... Xreturn} make thread for {}, push stdout + * Xbackq(split){... Xreturn} make thread for {}, push stdout * Xbang complement condition * Xcase(pat, value){...} exec code on match, leave (value) on * stack @@ -215,18 +229,15 @@ main(int argc, char *argv[]) * Xconc(left, right) concatenate, push results * Xcount(name) push var count * Xdelfn(name) delete function definition - * Xdelhere + * Xdeltraps(names) delete named traps * Xdol(name) get variable value + * Xqdol(name) concatenate variable components * Xdup[i j] dup file descriptor - * Xeflag - * Xerror * Xexit rc exits with status * Xfalse{...} execute {} if false * Xfn(name){... Xreturn} define function * Xfor(var, list){... Xreturn} for loop - * Xglob - * Xif - * Xifnot + * Xglobs[string globsize] push globbing string * Xjump[addr] goto * Xlocal(name, val) create local variable, assign value * Xmark mark stack @@ -235,21 +246,16 @@ main(int argc, char *argv[]) * wait for both * Xpipefd[type]{... Xreturn} connect {} to pipe (input or output, * depending on type), push /dev/fd/?? - * Xpipewait * Xpopm(value) pop value from stack - * Xpopredir - * Xrdcmds - * Xrdfn * Xrdwr(file)[fd] open file for reading and writing * Xread(file)[fd] open file to read - * Xqdol(name) concatenate variable components - * Xreturn kill thread + * Xsettraps(names){... Xreturn} define trap functions + * Xshowtraps print trap list * Xsimple(args) run command and wait - * Xsub + * Xreturn kill thread * Xsubshell{... Xexit} execute {} in a subshell and wait * Xtrue{...} execute {} if true * Xunlocal delete local variable - * Xwastrue * Xword[string] push string * Xwrite(file)[fd] open file to write */ @@ -326,7 +332,7 @@ Xexit(void) --runq->pc; starval = vlook("*")->val; start(trapreq->fn, trapreq->pc, (struct var *)0); - runq->local = newvar(strdup("*"), runq->local); + runq->local = newvar("*", runq->local); runq->local->val = copywords(starval, (struct word *)0); runq->local->changed = 1; runq->redir = runq->startredir = 0; @@ -440,7 +446,7 @@ Xpopredir(void) runq->redir = rp->next; if(rp->type==ROPEN) close(rp->from); - efree((char *)rp); + free(rp); } void @@ -451,7 +457,7 @@ Xreturn(void) while(p->argv) poplist(); codefree(p->code); runq = p->ret; - efree((char *)p); + free(p); if(runq==0) Exit(getstatus()); } @@ -483,6 +489,13 @@ Xword(void) pushword(runq->code[runq->pc++].s); } +void +Xglobs(void) +{ + word *w = pushword(runq->code[runq->pc++].s); + w->glob = runq->code[runq->pc++].i; +} + void Xwrite(void) { @@ -541,7 +554,7 @@ Xmatch(void) setstatus(""); break; } - efree(subject); + free(subject); poplist(); poplist(); } @@ -559,7 +572,7 @@ Xcase(void) break; } } - efree(s); + free(s); if(ok) runq->pc++; else @@ -570,16 +583,25 @@ Xcase(void) word* conclist(word *lp, word *rp, word *tail) { - char *buf; - word *v; - if(lp->next || rp->next) - tail = conclist(lp->next==0? lp: lp->next, - rp->next==0? rp: rp->next, tail); - buf = emalloc(strlen(lp->word)+strlen((char *)rp->word)+1); - strcpy(buf, lp->word); - strcat(buf, rp->word); - v = newword(buf, tail); - efree(buf); + word *v, *p, **end; + int ln, rn; + + for(end = &v;;){ + ln = strlen(lp->word), rn = strlen(rp->word); + p = Newword(emalloc(ln+rn+1), (word *)0); + memmove(p->word, lp->word, ln); + memmove(p->word+ln, rp->word, rn+1); + if(lp->glob || rp->glob) + p->glob = Globsize(p->word); + *end = p, end = &p->next; + if(lp->next == 0 && rp->next == 0) + break; + if(lp->next) + lp = lp->next; + if(rp->next) + rp = rp->next; + } + *end = tail; return v; } @@ -606,6 +628,17 @@ Xconc(void) runq->argv->words = vp; } +char* +Str(word *a) +{ + char *s = a->word; + if(a->glob){ + a->glob = 0; + deglob(s); + } + return s; +} + void Xassign(void) { @@ -614,12 +647,10 @@ Xassign(void) Xerror1("variable name not singleton!"); return; } - deglob(runq->argv->words->word); - v = vlook(runq->argv->words->word); + v = vlook(Str(runq->argv->words)); poplist(); - globlist(); freewords(v->val); - v->val = runq->argv->words; + v->val = globlist(runq->argv->words); v->changed = 1; runq->argv->words = 0; poplist(); @@ -648,8 +679,7 @@ Xdol(void) Xerror1("variable name not singleton!"); return; } - s = runq->argv->words->word; - deglob(s); + s = Str(runq->argv->words); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; a = runq->argv->next->words; @@ -669,35 +699,17 @@ Xdol(void) void Xqdol(void) { - word *a, *p; + word *a; char *s; - int n; + if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } - s = runq->argv->words->word; - deglob(s); + s = Str(runq->argv->words); a = vlook(s)->val; poplist(); - n = count(a); - if(n==0){ - pushword(""); - return; - } - for(p = a;p;p = p->next) n+=strlen(p->word); - s = emalloc(n); - if(a){ - strcpy(s, a->word); - for(p = a->next;p;p = p->next){ - strcat(s, " "); - strcat(s, p->word); - } - } - else - s[0]='\0'; - pushword(s); - efree(s); + Pushword(list2str(a)); } word* @@ -724,8 +736,7 @@ subwords(word *val, int len, word *sub, word *a) if(!sub) return a; a = subwords(val, len, sub->next, a); - s = sub->word; - deglob(s); + s = Str(sub); m = 0; n = 0; while('0'<=*s && *s<='9') @@ -757,8 +768,7 @@ Xsub(void) Xerror1("variable name not singleton!"); return; } - s = runq->argv->next->words->word; - deglob(s); + s = Str(runq->argv->next->words); a = runq->argv->next->next->words; v = vlook(s)->val; a = subwords(v, count(v), runq->argv->words, a); @@ -801,11 +811,9 @@ Xlocal(void) Xerror1("variable name must be singleton\n"); return; } - deglob(runq->argv->words->word); - runq->local = newvar(strdup(runq->argv->words->word), runq->local); + runq->local = newvar(Str(runq->argv->words), runq->local); poplist(); - globlist(); - runq->local->val = runq->argv->words; + runq->local->val = globlist(runq->argv->words); runq->local->changed = 1; runq->argv->words = 0; poplist(); @@ -820,9 +828,9 @@ Xunlocal(void) runq->local = v->next; hid = vlook(v->name); hid->changed = 1; - efree(v->name); + free(v->name); freewords(v->val); - efree((char *)v); + free(v); } void @@ -830,9 +838,9 @@ freewords(word *w) { word *nw; while(w){ - efree(w->word); + free(w->word); nw = w->next; - efree((char *)w); + free(w); w = nw; } } @@ -844,8 +852,7 @@ Xfn(void) word *a; int end; end = runq->code[runq->pc].i; - globlist(); - for(a = runq->argv->words;a;a = a->next){ + for(a = globlist(runq->argv->words);a;a = a->next){ v = gvlook(a->word); if(v->fn) codefree(v->fn); @@ -921,7 +928,7 @@ Xrdcmds(void) if(yyparse()){ if(!p->iflag || p->eof && !Eintr()){ if(p->cmdfile) - efree(p->cmdfile); + free(p->cmdfile); closeio(p->cmdfd); Xreturn(); /* should this be omitted? */ } @@ -1014,5 +1021,5 @@ Xfor(void) void Xglob(void) { - globlist(); + globlist(runq->argv->words); } diff --git a/sys/src/cmd/rc/exec.h b/sys/src/cmd/rc/exec.h index 960cc0a..d2fdfa3 100644 --- a/sys/src/cmd/rc/exec.h +++ b/sys/src/cmd/rc/exec.h @@ -16,7 +16,7 @@ extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); extern void Xrdwr(void); extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); -extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void); +extern void Xtrue(void), Xword(void), Xglobs(void), Xwrite(void), Xpipefd(void), Xcase(void); extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); extern void Xrdcmds(void), Xwastrue(void), Xif(void), Xifnot(void), Xpipewait(void); extern void Xdelhere(void), Xpopredir(void), Xsub(void), Xeflag(void), Xsettrue(void); @@ -29,6 +29,7 @@ extern void Xerror1(char*); struct word{ char *word; word *next; + int glob; /* Globsize(word) */ }; struct list{ word *words; @@ -76,7 +77,6 @@ struct builtin{ }; extern struct builtin Builtin[]; int eflagok; /* kludge flag so that -e doesn't exit in startup */ -int havefork; void execcd(void), execwhatis(void), execeval(void), execexec(void); int execforkexec(void); diff --git a/sys/src/cmd/rc/fns.h b/sys/src/cmd/rc/fns.h index 7f9b6d3..d617e87 100644 --- a/sys/src/cmd/rc/fns.h +++ b/sys/src/cmd/rc/fns.h @@ -19,18 +19,17 @@ void Exit(char*); int ForkExecute(char*, char**, int, int, int); int Globsize(char*); int Isatty(int); -void Memcpy(void*, void*, int32_t); void Noerror(void); int Opendir(char*); -int32_t Read(int, void*, int32_t); +int Read(int, void*, int); int Readdir(int, void*, int); -int32_t Seek(int, int32_t, int32_t); +int Seek(int, int, int); void Trapinit(void); void Unlink(char*); void Updenv(void); void Vinit(void); int Waitfor(int, int); -int32_t Write(int, void*, int32_t); +int Write(int, void*, int); void addwaitpid(int); int advance(void); int back(int); @@ -39,19 +38,18 @@ void codefree(code*); int compile(tree*); char * list2str(word*); int count(word*); -void deglob(void*); +char* deglob(char*); void delwaitpid(int); void dotrap(void); void freenodes(void); void freewords(word*); -void globlist(void); +word* globlist(word*); int havewaitpid(int); int idchr(int); -void inttoascii(char*, int32_t); +void inttoascii(char*, int); void kinit(void); int mapfd(int); -int match(void*, void*, int); -int matchfn(void*, void*); +int match(char*, char*, int); char** mkargv(word*); void clearwaitpids(void); void panic(char*, int); @@ -61,7 +59,7 @@ void popword(void); void pprompt(void); void pushlist(void); void pushredir(int, int, int); -void pushword(char*); +word* pushword(char*); void readhere(void); word* searchpath(char*); void setstatus(char*); diff --git a/sys/src/cmd/rc/glob.c b/sys/src/cmd/rc/glob.c index e27754f..c9b8c71 100644 --- a/sys/src/cmd/rc/glob.c +++ b/sys/src/cmd/rc/glob.c @@ -10,22 +10,22 @@ #include "rc.h" #include "exec.h" #include "fns.h" -char *globname; -struct word *globv; + /* * delete all the GLOB marks from s, in place */ -void -deglob(void *as) +char* +deglob(char *s) { - char *s = as; + char *b = s; char *t = s; do{ if(*t==GLOB) t++; *s++=*t; }while(*t++); + return b; } int @@ -45,23 +45,33 @@ globsort(word *left, word *right) for(a = left,n = 0;a!=right;a = a->next,n++) list[n] = a->word; qsort((void *)list, n, sizeof(void *), globcmp); for(a = left,n = 0;a!=right;a = a->next,n++) a->word = list[n]; - efree((char *)list); + free(list); } + /* - * Push names prefixed by globname and suffixed by a match of p onto the astack. - * namep points to the end of the prefix in globname. + * Does the string s match the pattern p + * . and .. are only matched by patterns starting with . + * * matches any sequence of characters + * ? matches any single character + * [...] matches the enclosed list of characters */ -void -globdir(uint8_t *p, uint8_t *namep) +static int +matchfn(char *s, char *p) { - uint8_t *t, *newp; + if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.') + return 0; + return match(s, p, '/'); +} + +static word* +globdir(word *list, char *p, char *name, char *namep) +{ + char *t, *newp; int f; /* scan the pattern looking for a component with a metacharacter in it */ - if(*p=='\0'){ - globv = newword(globname, globv); - return; - } + if(*p=='\0') + return newword(name, list); t = namep; newp = p; while(*newp){ @@ -76,64 +86,63 @@ globdir(uint8_t *p, uint8_t *namep) /* If we ran out of pattern, append the name if accessible */ if(*newp=='\0'){ *t='\0'; - if(access(globname, AEXIST)==0) - globv = newword(globname, globv); - return; + if(access(name, AEXIST)==0) + list = newword(name, list); + return list; } /* read the directory and recur for any entry that matches */ *namep='\0'; - if((f = Opendir(globname[0]?globname:"."))<0) return; - while(*newp!='/' && *newp!='\0') newp++; - while(Readdir(f, namep, *newp=='/')){ - if(matchfn(namep, p)){ - for(t = namep;*t;t++); - globdir(newp, t); + if((f = Opendir(name[0]?name:".")) >= 0){ + while(*newp!='/' && *newp!='\0') newp++; + while(Readdir(f, namep, *newp=='/')){ + if(matchfn(namep, p)){ + for(t = namep;*t;t++); + list = globdir(list, newp, name, t); + } } + Closedir(f); } - Closedir(f); + return list; } + /* - * Push all file names matched by p on the current thread's stack. - * If there are no matches, the list consists of p. + * Subsitute a word with its glob in place. */ -void -glob(void *ap) +static void +globword(word *w) { - uint8_t *p = ap; - word *svglobv = globv; - int globlen = Globsize(ap); + word *left, *right; + char *name; - if(!globlen){ - deglob(p); - globv = newword((char *)p, globv); + if(w->glob == 0) return; + name = emalloc(w->glob); + memset(name, 0, w->glob); + right = w->next; + left = globdir(right, w->word, name, name); + free(name); + if(left == right) { + deglob(w->word); + w->glob = 0; + } else { + free(w->word); + globsort(left, right); + *w = *left; + free(left); } - globname = emalloc(globlen); - globname[0]='\0'; - globdir(p, (uint8_t *)globname); - efree(globname); - if(svglobv==globv){ - deglob(p); - globv = newword((char *)p, globv); - } - else - globsort(globv, svglobv); } -/* - * Do p and q point at equal utf codes - */ -int -equtf(uint8_t *p, uint8_t *q) +word* +globlist(word *l) { - Rune pr, qr; - if(*p!=*q) - return 0; + word *p, *q; - chartorune(&pr, (char*)p); - chartorune(&qr, (char*)q); - return pr == qr; + for(p=l;p;p=q){ + q = p->next; + globword(p); + } + return l; } /* @@ -141,49 +150,43 @@ equtf(uint8_t *p, uint8_t *q) * not jumping past nuls in broken utf codes! */ -uint8_t* -nextutf(uint8_t *p) +static char* +nextutf(char *p) { Rune dummy; - return p + chartorune(&dummy, (char*)p); + + return p + chartorune(&dummy, p); } /* * Convert the utf code at *p to a unicode value */ -int -unicode(uint8_t *p) +static int +unicode(char *p) { Rune r; - chartorune(&r, (char*)p); + chartorune(&r, p); return r; } /* - * Does the string s match the pattern p - * . and .. are only matched by patterns starting with . - * * matches any sequence of characters - * ? matches any single character - * [...] matches the enclosed list of characters + * Do p and q point at equal utf codes */ -int -matchfn(void *as, void *ap) +static int +equtf(char *p, char *q) { - uint8_t *s = as, *p = ap; - - if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.') - return 0; - return match(s, p, '/'); + if(*p!=*q) + return 0; + return unicode(p) == unicode(q); } int -match(void *as, void *ap, int stop) +match(char *s, char *p, int stop) { int compl, hit, lo, hi, t, c; - uint8_t *s = as, *p = ap; for(; *p!=stop && *p!='\0'; s = nextutf(s), p = nextutf(p)){ if(*p!=GLOB){ @@ -242,27 +245,3 @@ match(void *as, void *ap, int stop) } return *s=='\0'; } - -void -globlist1(word *gl) -{ - if(gl){ - globlist1(gl->next); - glob(gl->word); - } -} - -void -globlist(void) -{ - word *a; - globv = 0; - globlist1(runq->argv->words); - poplist(); - pushlist(); - if(globv){ - for(a = globv;a->next;a = a->next); - a->next = runq->argv->words; - runq->argv->words = globv; - } -} diff --git a/sys/src/cmd/rc/havefork.c b/sys/src/cmd/rc/havefork.c index 6e2f8b0..11518a0 100644 --- a/sys/src/cmd/rc/havefork.c +++ b/sys/src/cmd/rc/havefork.c @@ -12,9 +12,6 @@ #include "exec.h" #include "io.h" #include "fns.h" -#include - -int havefork = 1; void Xasync(void) @@ -22,10 +19,12 @@ Xasync(void) int null = open("/dev/null", OREAD); int pid; char npid[10]; + if(null<0){ Xerror("Can't open /dev/null\n"); return; } + Updenv(); switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){ case -1: close(null); @@ -55,10 +54,12 @@ Xpipe(void) int lfd = p->code[pc++].i; int rfd = p->code[pc++].i; int pfd[2]; + if(pipe(pfd)<0){ Xerror("can't get pipe"); return; } + Updenv(); switch(forkid = fork()){ case -1: Xerror("try again"); @@ -84,25 +85,25 @@ Xpipe(void) /* * Who should wait for the exit from the fork? */ +enum { Stralloc = 100, }; void Xbackq(void) { - int n, pid; + int c, l, pid; int pfd[2]; - char *stop; - char utf[UTFmax+1]; + char *s, *wd, *ewd, *stop; struct io *f; - var *ifs = vlook("ifs"); word *v, *nextv; - Rune r; - String *word; - stop = ifs->val? ifs->val->word: ""; + stop = ""; + if(runq->argv && runq->argv->words) + stop = runq->argv->words->word; if(pipe(pfd)<0){ Xerror("can't make pipe"); return; } + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); @@ -119,28 +120,32 @@ Xbackq(void) addwaitpid(pid); close(pfd[PWR]); f = openfd(pfd[PRD]); - word = s_new(); - v = nil; - /* rutf requires at least UTFmax+1 bytes in utf */ - while((n = rutf(f, utf, &r)) != EOF){ - utf[n] = '\0'; - if(utfutf(stop, utf) == nil) - s_nappend(word, utf, n); - else - /* - * utf/r is an ifs rune (e.g., \t, \n), thus - * ends the current word, if any. - */ - if(s_len(word) > 0){ - v = newword(s_to_c(word), v); - s_reset(word); + s = wd = ewd = 0; + v = 0; + while((c = rchr(f))!=EOF){ + if(s==ewd){ + l = s-wd; + wd = erealloc(wd, l+Stralloc); + ewd = wd+l+Stralloc-1; + s = wd+l; + } + if(strchr(stop, c)){ + if(s!=wd){ + *s='\0'; + v = newword(wd, v); + s = wd; } + } + else *s++=c; } - if(s_len(word) > 0) - v = newword(s_to_c(word), v); - s_free(word); + if(s!=wd){ + *s='\0'; + v = newword(wd, v); + } + free(wd); closeio(f); Waitfor(pid, 0); + poplist(); /* ditch split in "stop" */ /* v points to reversed arglist -- reverse it onto argv */ while(v){ nextv = v->next; @@ -161,6 +166,7 @@ Xpipefd(void) char name[40]; int pfd[2]; int sidefd, mainfd; + if(pipe(pfd)<0){ Xerror("can't get pipe"); return; @@ -173,6 +179,7 @@ Xpipefd(void) sidefd = pfd[PRD]; mainfd = pfd[PWR]; } + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); @@ -200,6 +207,8 @@ void Xsubshell(void) { int pid; + + Updenv(); switch(pid = fork()){ case -1: Xerror("try again"); diff --git a/sys/src/cmd/rc/haventfork.c b/sys/src/cmd/rc/haventfork.c deleted file mode 100644 index 8587989..0000000 --- a/sys/src/cmd/rc/haventfork.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. - */ - -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -int havefork = 0; - -static char ** -rcargv(char *s) -{ - int argc; - char **argv; - word *p; - - p = vlook("*")->val; - argv = emalloc((count(p)+6)*sizeof(char*)); - argc = 0; - argv[argc++] = argv0; - if(flag['e']) - argv[argc++] = "-Se"; - else - argv[argc++] = "-S"; - argv[argc++] = "-c"; - argv[argc++] = s; - for(p = vlook("*")->val; p; p = p->next) - argv[argc++] = p->word; - argv[argc] = 0; - return argv; -} - -void -Xasync(void) -{ - uint32_t pid; - char buf[20], **argv; - - Updenv(); - - argv = rcargv(runq->code[runq->pc].s); - pid = ForkExecute(argv0, argv, -1, 1, 2); - free(argv); - - if(pid == 0) { - Xerror("proc failed"); - return; - } - - runq->pc++; - sprint(buf, "%d", pid); - setvar("apid", newword(buf, (word *)0)); -} - -void -Xbackq(void) -{ - char wd[8193], **argv; - int c; - char *s, *ewd=&wd[8192], *stop; - struct io *f; - var *ifs = vlook("ifs"); - word *v, *nextv; - int pfd[2]; - int pid; - - stop = ifs->val?ifs->val->word:""; - if(pipe(pfd)<0){ - Xerror("can't make pipe"); - return; - } - - Updenv(); - - argv = rcargv(runq->code[runq->pc].s); - pid = ForkExecute(argv0, argv, -1, pfd[1], 2); - free(argv); - - close(pfd[1]); - - if(pid == 0) { - Xerror("proc failed"); - close(pfd[0]); - return; - } - - f = openfd(pfd[0]); - s = wd; - v = 0; - while((c=rchr(f))!=EOF){ - if(strchr(stop, c) || s==ewd){ - if(s!=wd){ - *s='\0'; - v=newword(wd, v); - s=wd; - } - } - else *s++=c; - } - if(s!=wd){ - *s='\0'; - v=newword(wd, v); - } - closeio(f); - Waitfor(pid, 1); - /* v points to reversed arglist -- reverse it onto argv */ - while(v){ - nextv=v->next; - v->next=runq->argv->words; - runq->argv->words=v; - v=nextv; - } - runq->pc++; -} - -void -Xpipe(void) -{ - thread *p=runq; - int pc=p->pc, pid; - int rfd=p->code[pc+1].i; - int pfd[2]; - char **argv; - - if(pipe(pfd)<0){ - Xerror1("can't get pipe"); - return; - } - - Updenv(); - - argv = rcargv(runq->code[pc+2].s); - pid = ForkExecute(argv0, argv, 0, pfd[1], 2); - free(argv); - close(pfd[1]); - - if(pid == 0) { - Xerror("proc failed"); - close(pfd[0]); - return; - } - - start(p->code, pc+4, runq->local); - pushredir(ROPEN, pfd[0], rfd); - p->pc=p->code[pc+3].i; - p->pid=pid; -} - -void -Xpipefd(void) -{ - Abort(); -} - -void -Xsubshell(void) -{ - char **argv; - int pid; - - Updenv(); - - argv = rcargv(runq->code[runq->pc].s); - pid = ForkExecute(argv0, argv, -1, 1, 2); - free(argv); - - if(pid < 0) { - Xerror("proc failed"); - return; - } - - Waitfor(pid, 1); - runq->pc++; -} - -/* - * start a process running the cmd on the stack and return its pid. - */ -int -execforkexec(void) -{ - char **argv; - char file[1024]; - int nc; - word *path; - int pid; - - if(runq->argv->words==0) - return -1; - argv = mkargv(runq->argv->words); - - for(path = searchpath(runq->argv->words->word);path;path = path->next){ - nc = strlen(path->word); - if(nc < sizeof file - 1){ /* 1 for / */ - strcpy(file, path->word); - if(file[0]){ - strcat(file, "/"); - nc++; - } - if(nc+strlen(argv[1])= 0){ - free(argv); - return pid; - } - } - } - } - free(argv); - return -1; -} diff --git a/sys/src/cmd/rc/here.c b/sys/src/cmd/rc/here.c index 5373ac4..f9a197f 100644 --- a/sys/src/cmd/rc/here.c +++ b/sys/src/cmd/rc/here.c @@ -14,8 +14,8 @@ struct here *here, **ehere; int ser = 0; -char tmp[] = "/tmp/here0000.0000"; -char hex[] = "0123456789abcdef"; +char tmp[]="/tmp/here0000.0000"; +char hex[]="0123456789abcdef"; void psubst(io*, uint8_t*); void pstrs(io*, word*); @@ -45,7 +45,7 @@ heredoc(tree *tag) h->tag = tag; hexnum(&tmp[9], getpid()); hexnum(&tmp[14], ser++); - h->name = strdup(tmp); + h->name = estrdup(tmp); return token(tmp, WORD); } @@ -58,25 +58,24 @@ heredoc(tree *tag) void readhere(void) { - int c, subst; - char *s, *tag; - char line[NLINE+1]; - io *f; struct here *h, *nexth; - - for(h = here; h; h = nexth){ - subst = !h->tag->quoted; + io *f; + char *s, *tag; + int c, subst; + char line[NLINE+1]; + for(h = here;h;h = nexth){ + subst=!h->tag->quoted; tag = h->tag->str; c = Creat(h->name); - if(c < 0) + if(c<0) yyerror("can't create here document"); f = openfd(c); s = line; pprompt(); while((c = rchr(runq->cmdfd)) != EOF){ if(c == '\n' || s == &line[NLINE]){ - *s = '\0'; - if(tag && strcmp(line, tag) == 0) + *s='\0'; + if(tag && strcmp(line, tag)==0) break; if(subst) psubst(f, (uint8_t *)line); @@ -95,7 +94,7 @@ readhere(void) closeio(f); cleanhere(h->name); nexth = h->next; - efree((char *)h); + free(h); } here = 0; doprompt = 1; @@ -106,19 +105,26 @@ psubst(io *f, uint8_t *s) { int savec, n; uint8_t *t, *u; - Rune r; word *star; while(*s){ - if(*s != '$'){ /* copy plain text rune */ - if(*s < Runeself) + if(*s != '$'){ + if(0xa0 <= *s && *s <= 0xf5){ pchr(f, *s++); - else{ - n = chartorune(&r, (char *)s); - while(n-- > 0) - pchr(f, *s++); + if(*s == '\0') + break; } - }else{ /* $something -- perform substitution */ + else if(0xf6 <= *s && *s <= 0xf7){ + pchr(f, *s++); + if(*s == '\0') + break; + pchr(f, *s++); + if(*s == '\0') + break; + } + pchr(f, *s++); + } + else{ t = ++s; if(*t == '$') pchr(f, *t++); @@ -130,14 +136,15 @@ psubst(io *f, uint8_t *s) n = 0; for(u = s; *u && '0' <= *u && *u <= '9'; u++) n = n*10 + *u - '0'; - if(n && *u == '\0'){ + if(n && *u=='\0'){ star = vlook("*")->val; if(star && 1 <= n && n <= count(star)){ while(--n) star = star->next; pstr(f, star->word); } - }else + } + else pstrs(f, vlook((char *)s)->val); *t = savec; if(savec == '^') diff --git a/sys/src/cmd/rc/io.c b/sys/src/cmd/rc/io.c index fc1beec..afe3647 100644 --- a/sys/src/cmd/rc/io.c +++ b/sys/src/cmd/rc/io.c @@ -88,35 +88,6 @@ rchr(io *b) return *b->bufp++; } -int -rutf(io *b, char *buf, Rune *r) -{ - int n, i, c; - - c = rchr(b); - if(c == EOF) - return EOF; - *buf = c; - if(c < Runesync){ - *r = c; - return 1; - } - for(i = 1; (c = rchr(b)) != EOF; ){ - buf[i++] = c; - buf[i] = 0; - if(fullrune(buf, i)){ - n = chartorune(r, buf); - b->bufp -= i - n; /* push back unconsumed bytes */ - assert(b->fd == -1 || b->bufp > b->buf); - return n; - } - } - /* at eof */ - b->bufp -= i - 1; /* consume 1 byte */ - *r = Runeerror; - return runetochar(buf, r); -} - void pquo(io *f, char *s) { @@ -216,9 +187,7 @@ flush(io *f) if(f->strp){ n = f->ebuf - f->strp; - f->strp = realloc(f->strp, n+Stralloc+1); - if(f->strp==0) - panic("Can't realloc %d bytes in flush!", n+Stralloc+1); + f->strp = erealloc(f->strp, n+Stralloc+1); f->bufp = f->strp + n; f->ebuf = f->bufp + Stralloc; memset(f->bufp, '\0', Stralloc+1); @@ -270,7 +239,7 @@ opencore(char *s, int len) f->fd = -1 /*open("/dev/null", OREAD)*/; f->bufp = f->strp = buf; f->ebuf = buf+len; - Memcpy(buf, s, len); + memmove(buf, s, len); return f; } @@ -288,11 +257,11 @@ rewind(io *io) void closeio(io *io) { - if(io->fd>=0) + if(io->fd >= 0) close(io->fd); if(io->strp) - efree(io->strp); - efree(io); + free(io->strp); + free(io); } int diff --git a/sys/src/cmd/rc/io.h b/sys/src/cmd/rc/io.h index 670d365..542b88d 100644 --- a/sys/src/cmd/rc/io.h +++ b/sys/src/cmd/rc/io.h @@ -21,7 +21,6 @@ io *openfd(int), *openstr(void), *opencore(char *, int); int emptybuf(io*); void pchr(io*, int); int rchr(io*); -int rutf(io*, char*, Rune*); void closeio(io*); void flush(io*); int fullbuf(io*, int); diff --git a/sys/src/cmd/rc/lex.c b/sys/src/cmd/rc/lex.c index 92a4dda..546ea3d 100644 --- a/sys/src/cmd/rc/lex.c +++ b/sys/src/cmd/rc/lex.c @@ -101,6 +101,16 @@ pprompt(void) if(runq->iflag){ pstr(err, promptstr); flush(err); + if(newwdir){ + char dir[4096]; + int fd; + if((fd=open("/dev/wdir", OWRITE))>=0){ + getwd(dir, sizeof(dir)); + write(fd, dir, strlen(dir)); + close(fd); + } + newwdir = 0; + } prompt = vlook("prompt"); if(prompt->val && prompt->val->next) promptstr = prompt->val->next->word; @@ -163,7 +173,7 @@ addtok(char *p, int val) { if(p==0) return 0; - if(p >= &tok[NTOK]){ + if(p == &tok[NTOK-1]){ *p = 0; yyerror("token buffer too short"); return 0; @@ -179,7 +189,7 @@ addutf(char *p, int c) int i; p = addtok(p, c); /* 1-byte UTF runes are special */ - if(c < Runeself) + if(onebyte(c)) return p; m = 0xc0; diff --git a/sys/src/cmd/rc/pcmd.c b/sys/src/cmd/rc/pcmd.c index 268b887..16f031e 100644 --- a/sys/src/cmd/rc/pcmd.c +++ b/sys/src/cmd/rc/pcmd.c @@ -30,7 +30,6 @@ pcmd(io *f, tree *t) { if(t==0) return; - assert(f != nil); switch(t->type){ default: pfmt(f, "bad cmd %d %p %p %p", t->type, c0, c1, c2); break; @@ -42,7 +41,7 @@ pcmd(io *f, tree *t) break; case '^': pfmt(f, "%t^%t", c0, c1); break; - case '`': pfmt(f, "`%t", c0); + case '`': pfmt(f, "`%t%t", c0, c1); break; case ANDAND: pfmt(f, "%t && %t", c0, c1); break; diff --git a/sys/src/cmd/rc/pfnc.c b/sys/src/cmd/rc/pfnc.c index 1bcd8d1..32f9499 100644 --- a/sys/src/cmd/rc/pfnc.c +++ b/sys/src/cmd/rc/pfnc.c @@ -17,52 +17,51 @@ struct{ char *name; } fname[] = { Xappend, "Xappend", - Xassign, "Xassign", Xasync, "Xasync", - Xbackq, "Xbackq", Xbang, "Xbang", - Xcase, "Xcase", Xclose, "Xclose", - Xconc, "Xconc", - Xcount, "Xcount", - Xdelfn, "Xdelfn", - Xdelhere, "Xdelhere", - Xdol, "Xdol", Xdup, "Xdup", Xeflag, "Xeflag", - (void (*)(void))Xerror, "Xerror", Xexit, "Xexit", Xfalse, "Xfalse", - Xfn, "Xfn", - Xfor, "Xfor", - Xglob, "Xglob", - Xif, "Xif", Xifnot, "Xifnot", Xjump, "Xjump", - Xlocal, "Xlocal", Xmark, "Xmark", - Xmatch, "Xmatch", - Xpipe, "Xpipe", - Xpipefd, "Xpipefd", - Xpipewait, "Xpipewait", Xpopm, "Xpopm", - Xpopredir, "Xpopredir", - Xqdol, "Xqdol", - Xrdcmds, "Xrdcmds", - Xrdfn, "Xrdfn", Xrdwr, "Xrdwr", Xread, "Xread", Xreturn, "Xreturn", - Xsimple, "Xsimple", - Xsub, "Xsub", - Xsubshell, "Xsubshell", Xtrue, "Xtrue", - Xunlocal, "Xunlocal", + Xif, "Xif", Xwastrue, "Xwastrue", Xword, "Xword", Xwrite, "Xwrite", - 0 -}; + Xmatch, "Xmatch", + Xcase, "Xcase", + Xconc, "Xconc", + Xassign, "Xassign", + Xdol, "Xdol", + Xcount, "Xcount", + Xlocal, "Xlocal", + Xunlocal, "Xunlocal", + Xfn, "Xfn", + Xdelfn, "Xdelfn", + Xpipe, "Xpipe", + Xpipewait, "Xpipewait", + Xpopredir, "Xpopredir", + Xrdcmds, "Xrdcmds", + (void (*)(void))Xerror, "Xerror", + Xbackq, "Xbackq", + Xpipefd, "Xpipefd", + Xsubshell, "Xsubshell", + Xdelhere, "Xdelhere", + Xfor, "Xfor", + Xglob, "Xglob", + Xglobs, "Xglobs", + Xrdfn, "Xrdfn", + Xsimple, "Xsimple", + Xqdol, "Xqdol", +0}; void pfnc(io *fd, thread *t) @@ -72,14 +71,14 @@ pfnc(io *fd, thread *t) list *a; pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); - for (i = 0; fname[i].f; i++) - if (fname[i].f == fn) { + for(i = 0; fname[i].f; i++) + if(fname[i].f == fn){ pstr(fd, fname[i].name); break; } - if (!fname[i].f) + if(!fname[i].f) pfmt(fd, "%p", fn); - for (a = t->argv; a; a = a->next) + for(a = t->argv; a; a = a->next) pfmt(fd, " (%v)", a->words); pchr(fd, '\n'); flush(fd); diff --git a/sys/src/cmd/rc/plan9.c b/sys/src/cmd/rc/plan9.c index 711f5de..2a1f692 100644 --- a/sys/src/cmd/rc/plan9.c +++ b/sys/src/cmd/rc/plan9.c @@ -19,7 +19,7 @@ #include "getflags.h" enum { - Maxenvname = 256, /* undocumented limit */ + Maxenvname = 128, /* undocumented limit */ }; char *Signame[] = { @@ -155,7 +155,7 @@ Vinit(void) setvar(ent[i].name, val); vlook(ent[i].name)->changed = 0; close(f); - efree(buf); + free(buf); } } } @@ -163,42 +163,21 @@ Vinit(void) } close(dir); } -int envdir; void Xrdfn(void) { - int f, len; - Dir *e; - char envname[Maxenvname]; - static Dir *ent, *allocent; - static int nent; - - for(;;){ - if(nent == 0){ - free(allocent); - nent = dirread(envdir, &allocent); - ent = allocent; - } - if(nent <= 0) - break; - while(nent){ - e = ent++; - nent--; - len = e->length; - if(len && strncmp(e->name, "fn#", 3)==0){ - snprint(envname, sizeof envname, "/env/%s", e->name); - if((f = open(envname, OREAD))>=0){ - execcmds(openfd(f)); - return; - } - } - } + if(runq->argv->words == 0) + poplist(); + else { + int f = open(runq->argv->words->word, OREAD); + popword(); + runq->pc--; + if(f >= 0) + execcmds(openfd(f)); } - close(envdir); - Xreturn(); } -union code rdfns[4]; +union code rdfns[8]; void execfinit(void) @@ -206,17 +185,15 @@ execfinit(void) static int first = 1; if(first){ rdfns[0].i = 1; - rdfns[1].f = Xrdfn; - rdfns[2].f = Xjump; - rdfns[3].i = 1; + rdfns[1].f = Xmark; + rdfns[2].f = Xglobs; + rdfns[4].i = Globsize(rdfns[3].s = "/env/fn#\001*"); + rdfns[5].f = Xglob; + rdfns[6].f = Xrdfn; + rdfns[7].f = Xreturn; first = 0; } - Xpopm(); - envdir = open("/env", OREAD); - if(envdir<0){ - pfmt(err, "rc: can't open /env: %r\n"); - return; - } + poplist(); start(rdfns, 1, runq->local); } @@ -284,12 +261,10 @@ addenv(var *v) if((f = Creat(envname))<0) pfmt(err, "rc: can't open %s: %r\n", envname); else{ - if(v->fn){ - fd = openfd(f); + fd = openfd(f); + if(v->fn) pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s); - closeio(fd); - } - close(f); + closeio(fd); } } } @@ -318,71 +293,35 @@ Updenv(void) int ForkExecute(char *file, char **argv, int sin, int sout, int serr) { - int pid; - - if(access(file, AEXEC) != 0) - return -1; - switch(pid = fork()){ - case -1: - return -1; - case 0: - if(sin >= 0) - dup(sin, 0); - else - close(0); - if(sout >= 0) - dup(sout, 1); - else - close(1); - if(serr >= 0) - dup(serr, 2); - else - close(2); - exec(file, argv); - exits(file); - } - return pid; + return -1; } void Execute(word *args, word *path) { char **argv = mkargv(args); - char file[1024], errstr[1024]; - int nc; + char file[1024]; + int nc, mc; Updenv(); - errstr[0] = '\0'; + mc = strlen(argv[1])+1; for(;path;path = path->next){ nc = strlen(path->word); - if(nc < sizeof file - 1){ /* 1 for / */ - strcpy(file, path->word); - if(file[0]){ - strcat(file, "/"); - nc++; - } - if(nc + strlen(argv[1]) < sizeof file){ - strcat(file, argv[1]); - exec(file, argv+1); - rerrstr(errstr, sizeof errstr); - /* - * if file exists and is executable, exec should - * have worked, unless it's a directory or an - * executable for another architecture. in - * particular, if it failed due to lack of - * swap/vm (e.g., arg. list too long) or other - * allocation failure, stop searching and print - * the reason for failure. - */ - if (strstr(errstr, " allocat") != nil || - strstr(errstr, " full") != nil) - break; - } - else werrstr("command name too long"); + if(nc + mc >= sizeof file - 1){ /* 1 for / */ + werrstr("command path name too long"); + continue; } + if(nc > 0){ + memmove(file, path->word, nc); + file[nc++] = '/'; + } + memmove(file+nc, argv[1], mc); + exec(file, argv+1); } - pfmt(err, "%s: %s\n", argv[1], errstr); - efree((char *)argv); + rerrstr(file, sizeof file); + setstatus(file); + pfmt(err, "%s: %s\n", argv[1], file); + free(argv); } #define NDIR 256 /* shoud be a better way */ @@ -475,7 +414,7 @@ Again: } if(dir[f].i == dir[f].n) return 0; - strcpy(p, dir[f].dbuf[dir[f].i].name); + strncpy((char*)p, dir[f].dbuf[dir[f].i].name, NDIR); dir[f].i++; return 1; } @@ -527,20 +466,20 @@ Unlink(char *name) remove(name); } -int32_t -Write(int fd, void *buf, int32_t cnt) +int +Write(int fd, void *buf, int cnt) { return write(fd, buf, cnt); } -int32_t -Read(int fd, void *buf, int32_t cnt) +int +Read(int fd, void *buf, int cnt) { return read(fd, buf, cnt); } -int32_t -Seek(int fd, int32_t cnt, int32_t whence) +int +Seek(int fd, int cnt, int whence) { return seek(fd, cnt, whence); } @@ -621,27 +560,13 @@ Abort(void) Exit("aborting"); } -void -Memcpy(void *a, void *b, int32_t n) -{ - memmove(a, b, n); -} - -void* -Malloc(uint32_t n) -{ - return mallocz(n, 1); -} - int *waitpids; int nwaitpids; void addwaitpid(int pid) { - waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); - if(waitpids == 0) - panic("Can't realloc %d waitpids", nwaitpids+1); + waitpids = erealloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); waitpids[nwaitpids++] = pid; } diff --git a/sys/src/cmd/rc/rc.h b/sys/src/cmd/rc/rc.h index abb2969..497a8d7 100644 --- a/sys/src/cmd/rc/rc.h +++ b/sys/src/cmd/rc/rc.h @@ -6,14 +6,6 @@ * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ - -/* - * Assume plan 9 by default; if Unix is defined, assume unix. - * Please don't litter the code with ifdefs. The five below should be enough. - */ - -#ifndef Unix -/* plan 9 */ #include #include @@ -21,18 +13,6 @@ #define SIGINT 2 #define SIGQUIT 3 -#define fcntl(fd, op, arg) /* unix compatibility */ -#define F_SETFD -#define FD_CLOEXEC -#define YYSIZE_T size_t /* GNU Bison/yacc has hundred of types :( */ -#else -#include "unix.h" -#endif - -#ifndef ERRMAX -#define ERRMAX 128 -#endif - #define YYMAXDEPTH 500 #ifndef YYPREFIX #ifndef PAREN @@ -50,11 +30,6 @@ typedef struct redir redir; typedef struct thread thread; typedef struct builtin builtin; -#ifndef Unix -#pragma incomplete word -#pragma incomplete io -#endif - struct tree{ int type; int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ @@ -84,12 +59,13 @@ union code{ char *s; }; +int newwdir; char *promptstr; int doprompt; #define NTOK 8192 /* maximum bytes in a word (token) */ -char tok[NTOK + UTFmax]; +char tok[NTOK]; #define APPEND 1 #define WRITE 2 @@ -116,9 +92,11 @@ var *gvar[NVAR]; /* hash for globals */ #define new(type) ((type *)emalloc(sizeof(type))) -void *emalloc(int32_t); -void *Malloc(uint32_t); -void efree(void *); +void *emalloc(int); +void *erealloc(void *, int); +char *estrdup(char*); + +#define NOFILE 128 /* should come from */ struct here{ tree *tag; @@ -135,7 +113,12 @@ int mypid; * GLOB[...] matches anything in the brackets * GLOBGLOB matches GLOB */ -#define GLOB '\001' +#define GLOB ((char)0x01) +/* + * onebyte(c) + * Is c the first character of a one-byte utf sequence? + */ +#define onebyte(c) ((c&0x80)==0x00) char **argp; char **args; diff --git a/sys/src/cmd/rc/rcmain.unix b/sys/src/cmd/rc/rcmain.unix deleted file mode 100755 index 434d1ec..0000000 --- a/sys/src/cmd/rc/rcmain.unix +++ /dev/null @@ -1,34 +0,0 @@ -# rcmain: unix version -if(~ $#home 0) home=$HOME -if(~ $#ifs 0) ifs=' -' -switch($#prompt){ -case 0 - prompt=('% ' ' ') -case 1 - prompt=($prompt ' ') -} -if(~ $rcname ?.out) prompt=('broken! ' ' ') -if(flag p) path=/cmd -if not { - finit - if(~ $#path 0) path=(. /cmd /usr/cmd /usr/local/bin) -} -fn sigexit -if(! ~ $#cflag 0){ - if(flag l && test -r $home/lib/profile) . $home/lib/profile - status='' - eval $cflag -} -if not if(flag i){ - if(flag l && test -r $home/lib/profile) . $home/lib/profile - status='' - if(! ~ $#* 0) . $* - . -i /dev/fd/0 -} -if not if(~ $#* 0) . /dev/fd/0 -if not{ - status='' - . $* -} -exit $status diff --git a/sys/src/cmd/rc/run.unix b/sys/src/cmd/rc/run.unix deleted file mode 100755 index dd22f67..0000000 --- a/sys/src/cmd/rc/run.unix +++ /dev/null @@ -1,20 +0,0 @@ -yacc -d syn.y -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h -cc -DUnix -c -I. code.c -cc -DUnix -c -I. exec.c -cc -DUnix -c -I. getflags.c -cc -DUnix -c -I. glob.c -cc -DUnix -c -I. here.c -cc -DUnix -c -I. io.c -cc -DUnix -c -I. lex.c -cc -DUnix -c -I. pcmd.c -cc -DUnix -c -I. pfnc.c -cc -DUnix -c -I. simple.c -cc -DUnix -c -I. subr.c -cc -DUnix -c -I. trap.c -cc -DUnix -c -I. tree.c -cc -DUnix -c -I. var.c -cc -DUnix -c -I. havefork.c -cc -DUnix -c -I. unix.c -cc -DUnix -c -I. y.tab.c -cc -o rc code.o exec.o getflags.o glob.o here.o io.o lex.o pcmd.o pfnc.o simple.o subr.o trap.o tree.o var.o havefork.o unix.o y.tab.o diff --git a/sys/src/cmd/rc/simple.c b/sys/src/cmd/rc/simple.c index 6bcf6ec..465e349 100644 --- a/sys/src/cmd/rc/simple.c +++ b/sys/src/cmd/rc/simple.c @@ -29,18 +29,17 @@ void Xsimple(void) { word *a; - thread *p = runq; var *v; struct builtin *bp; int pid; - globlist(); - a = runq->argv->words; + + a = globlist(runq->argv->words); if(a==0){ Xerror1("empty argument list"); return; } if(flag['x']) - pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ + pfmt(err, "%v\n", a); /* wrong, should do redirs */ v = gvlook(a->word); if(v->fn) execfunc(v); @@ -64,7 +63,6 @@ Xsimple(void) /* fork and wait is redundant */ pushword("exec"); execexec(); - Xexit(); } else{ flush(err); @@ -129,6 +127,7 @@ execexec(void) doredir(runq->redir); Execute(runq->argv->words, searchpath(runq->argv->words->word)); poplist(); + Xexit(); } void @@ -140,7 +139,7 @@ execfunc(var *func) runq->argv->words = 0; poplist(); start(func->fn, func->pc, runq->local); - runq->local = newvar(strdup("*"), runq->local); + runq->local = newvar("*", runq->local); runq->local->val = starval; runq->local->changed = 1; } @@ -149,36 +148,12 @@ int dochdir(char *word) { /* report to /dev/wdir if it exists and we're interactive */ - static int wdirfd = -2; - if(chdir(word)<0) return -1; - if(flag['i']!=0){ - if(wdirfd==-2) /* try only once */ - wdirfd = open("/dev/wdir", OWRITE|OCEXEC); - if(wdirfd>=0) { - fcntl(wdirfd, F_SETFD, FD_CLOEXEC); - write(wdirfd, word, strlen(word)); - } - } + if(chdir(word)<0) + return -1; + newwdir = 1; return 1; } -static char * -appfile(char *dir, char *comp) -{ - int dirlen, complen; - char *s, *p; - - dirlen = strlen(dir); - complen = strlen(comp); - s = emalloc(dirlen + 1 + complen + 1); - memmove(s, dir, dirlen); - p = s + dirlen; - *p++ = '/'; - memmove(p, comp, complen); - p[complen] = '\0'; - return s; -} - void execcd(void) { @@ -197,9 +172,10 @@ execcd(void) cdpath = &nullpath; for(; cdpath; cdpath = cdpath->next){ if(cdpath->word[0] != '\0') - dir = appfile(cdpath->word, a->next->word); + dir = smprint("%s/%s", cdpath->word, + a->next->word); else - dir = strdup(a->next->word); + dir = estrdup(a->next->word); if(dochdir(dir) >= 0){ if(cdpath->word[0] != '\0' && @@ -261,10 +237,10 @@ execshift(void) break; } star = vlook("*"); - for(;n && star->val;--n){ + for(;n>0 && star->val;--n){ a = star->val->next; - efree(star->val->word); - efree((char *)star->val); + free(star->val->word); + free(star->val); star->val = a; star->changed = 1; } @@ -272,15 +248,6 @@ execshift(void) poplist(); } -int -octal(char *s) -{ - int n = 0; - while(*s==' ' || *s=='\t' || *s=='\n') s++; - while('0'<=*s && *s<='7') n = n*8+*s++-'0'; - return n; -} - int mapfd(int fd) { @@ -320,26 +287,19 @@ execcmds(io *f) void execeval(void) { - char *cmdline, *s, *t; - int len = 0; - word *ap; + char *cmdline; + int len; if(count(runq->argv->words)<=1){ Xerror1("Usage: eval cmd ..."); return; } eflagok = 1; - for(ap = runq->argv->words->next;ap;ap = ap->next) - len+=1+strlen(ap->word); - cmdline = emalloc(len); - s = cmdline; - for(ap = runq->argv->words->next;ap;ap = ap->next){ - for(t = ap->word;*t;) *s++=*t++; - *s++=' '; - } - s[-1]='\n'; + cmdline = list2str(runq->argv->words->next); + len = strlen(cmdline); + cmdline[len] = '\n'; poplist(); - execcmds(opencore(cmdline, len)); - efree(cmdline); + execcmds(opencore(cmdline, len+1)); + free(cmdline); } union code dotcmds[14]; @@ -382,14 +342,14 @@ execdot(void) Xerror1("Usage: . [-i] file [arg ...]"); return; } - zero = strdup(p->argv->words->word); + zero = estrdup(p->argv->words->word); popword(); fd = -1; for(path = searchpath(zero); path; path = path->next){ if(path->word[0] != '\0') - file = appfile(path->word, zero); + file = smprint("%s/%s", path->word, zero); else - file = strdup(zero); + file = estrdup(zero); fd = open(file, OREAD); free(file); @@ -420,7 +380,7 @@ execdot(void) /* free caller's copy of $* */ av = p->argv; p->argv = av->next; - efree((char *)av); + free(av); /* push $0 value */ pushlist(); pushword(zero); @@ -469,7 +429,6 @@ execwhatis(void){ /* mildly wrong -- should fork before writing */ return; } setstatus(""); - memset(out, 0, sizeof out); out->fd = mapfd(1); out->bufp = out->buf; out->ebuf = &out->buf[NBUF]; @@ -505,10 +464,10 @@ execwhatis(void){ /* mildly wrong -- should fork before writing */ for(path = searchpath(a->word); path; path = path->next){ if(path->word[0] != '\0') - file = appfile(path->word, - a->word); + file = smprint("%s/%s", + path->word, a->word); else - file = strdup(a->word); + file = estrdup(a->word); if(Executable(file)){ pfmt(out, "%s\n", file); free(file); diff --git a/sys/src/cmd/rc/subr.c b/sys/src/cmd/rc/subr.c index c630e8b..71bc1ae 100644 --- a/sys/src/cmd/rc/subr.c +++ b/sys/src/cmd/rc/subr.c @@ -13,24 +13,35 @@ #include "fns.h" void * -emalloc(int32_t n) +emalloc(int n) { - void *p = Malloc(n); - + void *p = malloc(n); if(p==0) panic("Can't malloc %d bytes", n); -/* if(err){ pfmt(err, "malloc %d->%p\n", n, p); flush(err); } */ return p; } -void -efree(void *p) +void* +erealloc(void *p, int n) { -/* pfmt(err, "free %p\n", p); flush(err); */ - if(p) - free(p); - else pfmt(err, "free 0\n"); + p = realloc(p, n); + if(p==0 && n!=0) + panic("Can't realloc %d bytes\n", n); + return p; } + +char* +estrdup(char *s) +{ + char *d; + int n; + + n = strlen(s)+1; + d = emalloc(n); + memmove(d, s, n); + return d; +} + extern int lastword, lastdol; void @@ -68,7 +79,7 @@ iacvt(int n) } void -inttoascii(char *s, int32_t n) +inttoascii(char *s, int n) { bp = s; iacvt(n); diff --git a/sys/src/cmd/rc/syn.y b/sys/src/cmd/rc/syn.y index c7de353..051c9e8 100644 --- a/sys/src/cmd/rc/syn.y +++ b/sys/src/cmd/rc/syn.y @@ -83,7 +83,8 @@ comword: '$' word {$$=tree1('$', $2);} | '"' word {$$=tree1('"', $2);} | COUNT word {$$=tree1(COUNT, $2);} | WORD -| '`' brace {$$=tree1('`', $2);} +| '`' brace {$$=tree2('`', (struct tree*)0, $2);} +| '`' word brace {$$=tree2('`', $2, $3);} | '(' words ')' {$$=tree1(PAREN, $2);} | REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;} keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN diff --git a/sys/src/cmd/rc/trap.c b/sys/src/cmd/rc/trap.c index b1ea495..ed0f715 100644 --- a/sys/src/cmd/rc/trap.c +++ b/sys/src/cmd/rc/trap.c @@ -27,7 +27,7 @@ dotrap(void) trapreq = vlook(Signame[i]); if(trapreq->fn){ start(trapreq->fn, trapreq->pc, (struct var *)0); - runq->local = newvar(strdup("*"), runq->local); + runq->local = newvar("*", runq->local); runq->local->val = copywords(starval, (struct word *)0); runq->local->changed = 1; runq->redir = runq->startredir = 0; diff --git a/sys/src/cmd/rc/tree.c b/sys/src/cmd/rc/tree.c index 6c5f188..3933f50 100644 --- a/sys/src/cmd/rc/tree.c +++ b/sys/src/cmd/rc/tree.c @@ -36,8 +36,8 @@ freenodes(void) for(t = treenodes;t;t = u){ u = t->next; if(t->str) - efree(t->str); - efree((char *)t); + free(t->str); + free(t); } treenodes = 0; } @@ -120,7 +120,7 @@ simplemung(tree *t) t = tree1(SIMPLE, t); s = openstr(); pfmt(s, "%t", t); - t->str = strdup((char *)s->strp); + t->str = estrdup((char *)s->strp); closeio(s); for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){ if(u->child[1]->type==DUP @@ -152,6 +152,6 @@ freetree(tree *p) freetree(p->child[1]); freetree(p->child[2]); if(p->str) - efree(p->str); - efree((char *)p); + free(p->str); + free(p); } diff --git a/sys/src/cmd/rc/unix.c b/sys/src/cmd/rc/unix.c deleted file mode 100644 index cf7b3cd..0000000 --- a/sys/src/cmd/rc/unix.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. - */ - -/* - * Unix versions of system-specific functions - * By convention, exported routines herein have names beginning with an - * upper case letter. - */ -#include "rc.h" -#include "io.h" -#include "exec.h" -#include "getflags.h" -#include - -char *Rcmain = "/usr/lib/rcmain"; -char *Fdprefix = "/dev/fd/"; - -void execfinit(void); - -struct builtin Builtin[] = { - "cd", execcd, - "whatis", execwhatis, - "eval", execeval, - "exec", execexec, /* but with popword first */ - "exit", execexit, - "shift", execshift, - "wait", execwait, - "umask", execumask, - ".", execdot, - "finit", execfinit, - "flag", execflag, - 0 -}; -#define SEP '\1' -char **environp; - -struct word* -enval(s) -register char *s; -{ - char *t, c; - struct word *v; - for(t = s;*t && *t!=SEP;t++); - c=*t; - *t='\0'; - v = newword(s, c=='\0'?(struct word *)0:enval(t+1)); - *t = c; - return v; -} - -void -Vinit(void) -{ - extern char **environ; - char *s; - char **env = environ; - environp = env; - for(;*env;env++){ - for(s=*env;*s && *s!='(' && *s!='=';s++); - switch(*s){ - case '\0': - pfmt(err, "environment %q?\n", *env); - break; - case '=': - *s='\0'; - setvar(*env, enval(s+1)); - *s='='; - break; - case '(': /* ignore functions for now */ - break; - } - } -} - -char **envp; - -void -Xrdfn(void) -{ - char *s; - int len; - for(;*envp;envp++){ - for(s=*envp;*s && *s!='(' && *s!='=';s++); - switch(*s){ - case '\0': - pfmt(err, "environment %q?\n", *envp); - break; - case '=': /* ignore variables */ - break; - case '(': /* Bourne again */ - s=*envp+3; - envp++; - len = strlen(s); - s[len]='\n'; - execcmds(opencore(s, len+1)); - s[len]='\0'; - return; - } - } - Xreturn(); -} - -union code rdfns[4]; - -void -execfinit(void) -{ - static int first = 1; - if(first){ - rdfns[0].i = 1; - rdfns[1].f = Xrdfn; - rdfns[2].f = Xjump; - rdfns[3].i = 1; - first = 0; - } - Xpopm(); - envp = environp; - start(rdfns, 1, runq->local); -} - -int -cmpenv(const void *aa, const void *ab) -{ - char **a = aa, **b = ab; - - return strcmp(*a, *b); -} - -char ** -mkenv(void) -{ - char **env, **ep, *p, *q; - struct var **h, *v; - struct word *a; - int nvar = 0, nchr = 0, sep; - - /* - * Slightly kludgy loops look at locals then globals. - * locals no longer exist - geoff - */ - for(h = gvar-1; h != &gvar[NVAR]; h++) - for(v = h >= gvar? *h: runq->local; v ;v = v->next){ - if((v==vlook(v->name)) && v->val){ - nvar++; - nchr+=strlen(v->name)+1; - for(a = v->val;a;a = a->next) - nchr+=strlen(a->word)+1; - } - if(v->fn){ - nvar++; - nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8; - } - } - env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr); - ep = env; - p = (char *)&env[nvar+1]; - for(h = gvar-1; h != &gvar[NVAR]; h++) - for(v = h >= gvar? *h: runq->local;v;v = v->next){ - if((v==vlook(v->name)) && v->val){ - *ep++=p; - q = v->name; - while(*q) *p++=*q++; - sep='='; - for(a = v->val;a;a = a->next){ - *p++=sep; - sep = SEP; - q = a->word; - while(*q) *p++=*q++; - } - *p++='\0'; - } - if(v->fn){ - *ep++=p; - *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */ - *p++='f'; *p++='n'; *p++=' '; - q = v->name; - while(*q) *p++=*q++; - *p++=' '; - q = v->fn[v->pc-1].s; - while(*q) *p++=*q++; - *p++='\0'; - } - } - *ep = 0; - qsort((void *)env, nvar, sizeof ep[0], cmpenv); - return env; -} -char *sigmsg[] = { -/* 0 normal */ 0, -/* 1 SIGHUP */ "Hangup", -/* 2 SIGINT */ 0, -/* 3 SIGQUIT */ "Quit", -/* 4 SIGILL */ "Illegal instruction", -/* 5 SIGTRAP */ "Trace/BPT trap", -/* 6 SIGIOT */ "abort", -/* 7 SIGEMT */ "EMT trap", -/* 8 SIGFPE */ "Floating exception", -/* 9 SIGKILL */ "Killed", -/* 10 SIGBUS */ "Bus error", -/* 11 SIGSEGV */ "Memory fault", -/* 12 SIGSYS */ "Bad system call", -/* 13 SIGPIPE */ 0, -/* 14 SIGALRM */ "Alarm call", -/* 15 SIGTERM */ "Terminated", -/* 16 unused */ "signal 16", -/* 17 SIGSTOP */ "Process stopped", -/* 18 unused */ "signal 18", -/* 19 SIGCONT */ "Process continued", -/* 20 SIGCHLD */ "Child death", -}; - -void -Waitfor(int pid, int persist) -{ - int wpid, sig; - struct thread *p; - int wstat; - char wstatstr[12]; - - for(;;){ - errno = 0; - wpid = wait(&wstat); - if(errno==EINTR && persist) - continue; - if(wpid==-1) - break; - sig = wstat&0177; - if(sig==0177){ - pfmt(err, "trace: "); - sig = (wstat>>8)&0177; - } - if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){ - if(pid!=wpid) - pfmt(err, "%d: ", wpid); - if(sig<=(sizeof sigmsg/sizeof sigmsg[0])) - pfmt(err, "%s", sigmsg[sig]); - else if(sig==0177) pfmt(err, "stopped by ptrace"); - else pfmt(err, "signal %d", sig); - if(wstat&0200)pfmt(err, " -- core dumped"); - pfmt(err, "\n"); - } - wstat = sig?sig+1000:(wstat>>8)&0xFF; - if(wpid==pid){ - inttoascii(wstatstr, wstat); - setstatus(wstatstr); - break; - } - else{ - for(p = runq->ret;p;p = p->ret) - if(p->pid==wpid){ - p->pid=-1; - inttoascii(p->status, wstat); - break; - } - } - } -} - -char ** -mkargv(a) -register struct word *a; -{ - char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); - char **argp = argv+1; /* leave one at front for runcoms */ - - for(;a;a = a->next) - *argp++=a->word; - *argp = 0; - return argv; -} - -void -Updenv(void) -{ -} - -void -Execute(struct word *args, struct word *path) -{ - char *msg="not found"; - int txtbusy = 0; - char **env = mkenv(); - char **argv = mkargv(args); - char file[512]; - - for(;path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, argv[1]); -ReExec: - execve(file, argv+1, env); - switch(errno){ - case ENOEXEC: - pfmt(err, "%s: Bourne again\n", argv[1]); - argv[0]="sh"; - argv[1] = strdup(file); - execve("/cmd/sh", argv, env); - goto Bad; - case ETXTBSY: - if(++txtbusy!=5){ - sleep(txtbusy); - goto ReExec; - } - msg="text busy"; goto Bad; - case EACCES: - msg="no access"; - break; - case ENOMEM: - msg="not enough memory"; goto Bad; - case E2BIG: - msg="too big"; goto Bad; - } - } -Bad: - pfmt(err, "%s: %s\n", argv[1], msg); - efree((char *)env); - efree((char *)argv); -} - -#define NDIR 14 /* should get this from param.h */ - -Globsize(p) -register char *p; -{ - int isglob = 0, globlen = NDIR+1; - for(;*p;p++){ - if(*p==GLOB){ - p++; - if(*p!=GLOB) - isglob++; - globlen+=*p=='*'?NDIR:1; - } - else - globlen++; - } - return isglob?globlen:0; -} - -#include -#include - -#define NDIRLIST 50 - -DIR *dirlist[NDIRLIST]; - -Opendir(name) -char *name; -{ - DIR **dp; - for(dp = dirlist;dp!=&dirlist[NDIRLIST];dp++) - if(*dp==0){ - *dp = opendir(name); - return *dp?dp-dirlist:-1; - } - return -1; -} - -int -Readdir(int f, char *p, int onlydirs) -{ - struct dirent *dp = readdir(dirlist[f]); - - if(dp==0) - return 0; - strcpy(p, dp->d_name); - return 1; -} - -void -Closedir(int f) -{ - closedir(dirlist[f]); - dirlist[f] = 0; -} - -char *Signame[] = { - "sigexit", "sighup", "sigint", "sigquit", - "sigill", "sigtrap", "sigiot", "sigemt", - "sigfpe", "sigkill", "sigbus", "sigsegv", - "sigsys", "sigpipe", "sigalrm", "sigterm", - "sig16", "sigstop", "sigtstp", "sigcont", - "sigchld", "sigttin", "sigttou", "sigtint", - "sigxcpu", "sigxfsz", "sig26", "sig27", - "sig28", "sig29", "sig30", "sig31", - 0, -}; - -void -gettrap(int sig) -{ - signal(sig, gettrap); - trap[sig]++; - ntrap++; - if(ntrap>=NSIG){ - pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig); - signal(SIGABRT, (void (*)())0); - kill(getpid(), SIGABRT); - } -} - -void -Trapinit(void) -{ - int i; - void (*sig)(); - - if(1 || flag['d']){ /* wrong!!! */ - sig = signal(SIGINT, gettrap); - if(sig==SIG_IGN) - signal(SIGINT, SIG_IGN); - } - else{ - for(i = 1;i<=NSIG;i++) if(i!=SIGCHLD){ - sig = signal(i, gettrap); - if(sig==SIG_IGN) - signal(i, SIG_IGN); - } - } -} - -Unlink(name) -char *name; -{ - return unlink(name); -} -Write(fd, buf, cnt) -char *buf; -{ - return write(fd, buf, cnt); -} -Read(fd, buf, cnt) -char *buf; -{ - return read(fd, buf, cnt); -} -Seek(fd, cnt, whence) -int32_t cnt; -{ - return lseek(fd, cnt, whence); -} -Executable(file) -char *file; -{ - return(access(file, AEXEC)==0); -} -Creat(file) -char *file; -{ - return creat(file, 0666); -} -Dup(a, b){ - return dup2(a, b); -} -Dup1(a){ - return dup(a); -} -/* - * Wrong: should go through components of a|b|c and return the maximum. - */ -void -Exit(char *stat) -{ - int n = 0; - - while(*stat){ - if(*stat!='|'){ - if(*stat<'0' || '9'<*stat) - exit(1); - else n = n*10+*stat-'0'; - } - stat++; - } - exit(n); -} -Eintr(){ - return errno==EINTR; -} - -void -Noerror() -{ - errno = 0; -} -Isatty(fd){ - return isatty(fd); -} - -void -Abort() -{ - abort(); -} - -void -execumask(void) /* wrong -- should fork before writing */ -{ - int m; - struct io out[1]; - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: umask [umask]\n"); - setstatus("umask usage"); - poplist(); - return; - case 2: - umask(octal(runq->argv->words->next->word)); - break; - case 1: - umask(m = umask(0)); - out->fd = mapfd(1); - out->bufp = out->buf; - out->ebuf=&out->buf[NBUF]; - out->strp = 0; - pfmt(out, "%o\n", m); - break; - } - setstatus(""); - poplist(); -} - -void -Memcpy(a, b, n) -int8_t *a, *b; -{ - memmove(a, b, n); -} - -void* -Malloc(unsigned long n) -{ - return (void *)malloc(n); -} - -void -errstr(char *buf, int len) -{ - strncpy(buf, strerror(errno), len); -} - -int -needsrcquote(int c) -{ - if(c <= ' ') - return 1; - if(strchr("`^#*[]=|\\?${}()'<>&;", c)) - return 1; - return 0; -} - -int -rfork(int bits) -{ - return fork(); -} - -int *waitpids; -int nwaitpids; - -void -addwaitpid(int pid) -{ - waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); - if(waitpids == 0) - panic("Can't realloc %d waitpids", nwaitpids+1); - waitpids[nwaitpids++] = pid; -} - -void -delwaitpid(int pid) -{ - int r, w; - - for(r=w=0; r -#include -#include -#include -#include -#include -#include - -#ifndef NSIG -#define NSIG 32 -#endif - -/* plan 9 compatibility */ -#define RFPROC 1 -#define RFFDG 1 -#define RFNOTEG 1 - -#define uintptr_t uintptr_t - -char *strdup(const char *); - -#define nil ((void*)0) - -/* in case uchar, etc. are built-in types */ -#define uchar _fmtuchar -#define ushort _fmtushort -#define uint32_t _fmtuint -#define ulong _fmtulong -#define vlong _fmtvlong -#define uvlong _fmtuvlong - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint32_t; -typedef unsigned long ulong; -typedef unsigned long long uvlong; - -#define OREAD O_RDONLY -#define OWRITE O_WRONLY -#define ORDWR O_RDWR -#define OCEXEC 0 diff --git a/sys/src/cmd/rc/var.c b/sys/src/cmd/rc/var.c index 6d94ce5..3110e59 100644 --- a/sys/src/cmd/rc/var.c +++ b/sys/src/cmd/rc/var.c @@ -11,17 +11,14 @@ #include "exec.h" #include "fns.h" -unsigned -hash(char *as, int n) +int +hash(char *s, int n) { - int i = 1; - unsigned h = 0; - uint8_t *s; - - s = (uint8_t *)as; - while (*s) + int h = 0, i = 1; + while(*s) h += *s++ * i++; - return h % n; + h%=n; + return h < 0 ? h+n : h; } #define NKW 30 @@ -76,8 +73,10 @@ gvlook(char *name) { int h = hash(name, NVAR); var *v; - for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return v; - return gvar[h] = newvar(strdup(name), gvar[h]); + for(v = gvar[h];v;v = v->next) + if(strcmp(v->name, name)==0) + return v; + return gvar[h] = newvar(name, gvar[h]); } var* diff --git a/sys/src/cmd/rc/win32.c b/sys/src/cmd/rc/win32.c deleted file mode 100644 index 534233a..0000000 --- a/sys/src/cmd/rc/win32.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. - */ - -/* - * Plan 9 versions of system-specific functions - * By convention, exported routines herein have names beginning with an - * upper case letter. - */ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -#include "getflags.h" -char *Signame[] = { - "sigexit", "sighup", "sigint", "sigquit", - "sigalrm", "sigkill", "sigfpe", "sigterm", - 0 -}; -char *syssigname[] = { - "exit", /* can't happen */ - "hangup", - "interrupt", - "quit", /* can't happen */ - "alarm", - "kill", - "sys: fp: ", - "term", - 0 -}; -char *Rcmain = "/rc/lib/rcmain"; -char *Fdprefix = "/fd/"; - -void execfinit(void); -void execbind(void); - -builtin Builtin[] = { - "cd", execcd, - "whatis", execwhatis, - "eval", execeval, - "exec", execexec, /* but with popword first */ - "exit", execexit, - "shift", execshift, - "wait", execwait, - ".", execdot, - "finit", execfinit, - "flag", execflag, - 0 -}; - -void -Vinit(void) -{ - int dir, f, len; - word *val; - char *buf, *s; - Dir *ent; - int i, nent; - char envname[256]; - dir = open("/env", OREAD); - if(dir<0){ - pfmt(err, "rc: can't open /env: %r\n"); - return; - } - ent = nil; - for(;;){ - nent = dirread(dir, &ent); - if(nent <= 0) - break; - for(i = 0; i=0){ - buf = emalloc((int)len+1); - read(f, buf, (int32_t)len); - val = 0; - /* Charitably add a 0 at the end if need be */ - if(buf[len-1]) - buf[len++]='\0'; - s = buf+len-1; - for(;;){ - while(s!=buf && s[-1]!='\0') --s; - val = newword(s, val); - if(s==buf) - break; - --s; - } - setvar(ent[i].name, val); - vlook(ent[i].name)->changed = 0; - close(f); - efree(buf); - } - } - } - free(ent); - } - close(dir); -} -int envdir; - -void -Xrdfn(void) -{ - int f, len; - static Dir *ent, *allocent; - static int nent; - Dir *e; - char envname[256]; - - for(;;){ - if(nent == 0){ - free(allocent); - nent = dirread(envdir, &allocent); - ent = allocent; - } - if(nent <= 0) - break; - while(nent){ - e = ent++; - nent--; - len = e->length; - if(len && strncmp(e->name, "fn#", 3)==0){ - snprint(envname, sizeof envname, "/env/%s", e->name); - if((f = open(envname, OREAD))>=0){ - execcmds(openfd(f)); - return; - } - } - } - } - close(envdir); - Xreturn(); -} -union code rdfns[4]; - -void -execfinit(void) -{ - static int first = 1; - if(first){ - rdfns[0].i = 1; - rdfns[1].f = Xrdfn; - rdfns[2].f = Xjump; - rdfns[3].i = 1; - first = 0; - } - Xpopm(); - envdir = open("/env", OREAD); - if(envdir<0){ - pfmt(err, "rc: can't open /env: %r\n"); - return; - } - start(rdfns, 1, runq->local); -} - -int -Waitfor(int pid, int persist) -{ - thread *p; - Waitmsg *w; - char errbuf[ERRMAX]; - - while((w = wait()) != nil){ - if(w->pid==pid){ - setstatus(w->msg); - free(w); - return 0; - } - for(p = runq->ret;p;p = p->ret) - if(p->pid==w->pid){ - p->pid=-1; - strcpy(p->status, w->msg); - } - free(w); - } - - errstr(errbuf, sizeof errbuf); - if(strcmp(errbuf, "interrupted")==0) return -1; - return 0; -} - -char* -*mkargv(word *a) -{ - char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); - char **argp = argv+1; /* leave one at front for runcoms */ - for(;a;a = a->next) *argp++=a->word; - *argp = 0; - return argv; -} - -void -addenv(var *v) -{ - char envname[256]; - word *w; - int f; - io *fd; - if(v->changed){ - v->changed = 0; - snprint(envname, sizeof envname, "/env/%s", v->name); - if((f = Creat(envname))<0) - pfmt(err, "rc: can't open %s: %r\n", envname); - else{ - for(w = v->val;w;w = w->next) - write(f, w->word, strlen(w->word)+1L); - close(f); - } - } - if(v->fnchanged){ - v->fnchanged = 0; - snprint(envname, sizeof envname, "/env/fn#%s", v->name); - if((f = Creat(envname))<0) - pfmt(err, "rc: can't open %s: %r\n", envname); - else{ - if(v->fn){ - fd = openfd(f); - pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s); - closeio(fd); - } - close(f); - } - } -} - -void -updenvlocal(var *v) -{ - if(v){ - updenvlocal(v->next); - addenv(v); - } -} - -void -Updenv(void) -{ - var *v, **h; - for(h = gvar;h!=&gvar[NVAR];h++) - for(v=*h;v;v = v->next) - addenv(v); - if(runq) - updenvlocal(runq->local); -} - -int -ForkExecute(char *file, char **argv, int sin, int sout, int serr) -{ - int pid; - -{int i; -fprint(2, "forkexec %s", file); -for(i = 0; argv[i]; i++)fprint(2, " %s", argv[i]); -fprint(2, " %d %d %d\n", sin, sout, serr); -} - if(access(file, AEXEC) != 0) - return -1; -fprint(2, "forking\n"); - switch(pid = fork()){ - case -1: - return -1; - case 0: - if(sin >= 0) - dup(sin, 0); - else - close(0); - if(sout >= 0) - dup(sout, 1); - else - close(1); - if(serr >= 0) - dup(serr, 2); - else - close(2); -fprint(2, "execing\n"); - exec(file, argv); -fprint(2, "exec: %r\n"); - exits(file); - } - return pid; -} - -void -Execute(word *args, word *path) -{ - char **argv = mkargv(args); - char file[1024]; - int nc; - Updenv(); - for(;path;path = path->next){ - nc = strlen(path->word); - if(nc<1024){ - strcpy(file, path->word); - if(file[0]){ - strcat(file, "/"); - nc++; - } - if(nc+strlen(argv[1])<1024){ - strcat(file, argv[1]); - exec(file, argv+1); - } - else werrstr("command name too long"); - } - } - rerrstr(file, sizeof file); - pfmt(err, "%s: %s\n", argv[1], file); - efree((char *)argv); -} -#define NDIR 256 /* shoud be a better way */ - -int -Globsize(char *p) -{ - int isglob = 0, globlen = NDIR+1; - for(;*p;p++){ - if(*p==GLOB){ - p++; - if(*p!=GLOB) - isglob++; - globlen+=*p=='*'?NDIR:1; - } - else - globlen++; - } - return isglob?globlen:0; -} -#define NFD 50 -#define NDBUF 32 -struct{ - Dir *dbuf; - int i; - int n; -}dir[NFD]; - -int -Opendir(char *name) -{ - Dir *db; - int f; - f = open(name, OREAD); - if(f==-1) - return f; - db = dirfstat(f); - if(db!=nil && (db->mode&DMDIR)){ - if(f=NFD) - return 0; -Again: - if(dir[f].i==dir[f].n){ /* read */ - free(dir[f].dbuf); - dir[f].dbuf = 0; - n = dirread(f, &dir[f].dbuf); - if(n>0){ - if(onlydirs){ - n = trimdirs(dir[f].dbuf, n); - if(n == 0) - goto Again; - } - dir[f].n = n; - }else - dir[f].n = 0; - dir[f].i = 0; - } - if(dir[f].i == dir[f].n) - return 0; - strcpy(p, dir[f].dbuf[dir[f].i].name); - dir[f].i++; - return 1; -} - -void -Closedir(int f) -{ - if(f>=0 && f=32){ /* rc is probably in a trap loop */ - pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); - abort(); - } - noted(NCONT); -} - -void -Trapinit(void) -{ - notify(notifyf); -} - -void -Unlink(char *name) -{ - remove(name); -} - -int32_t -Write(int fd, void *buf, int32_t cnt) -{ - return write(fd, buf, (int32_t)cnt); -} - -int32_t -Read(int fd, void *buf, int32_t cnt) -{ - return read(fd, buf, cnt); -} - -int32_t -Seek(int fd, int32_t cnt, int32_t whence) -{ - return seek(fd, cnt, whence); -} - -int -Executable(char *file) -{ - Dir *statbuf; - int ret; - - statbuf = dirstat(file); - if(statbuf == nil) - return 0; - ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); - free(statbuf); - return ret; -} - -int -Creat(char *file) -{ - return create(file, 1, 0666L); -} - -int -Dup(int a, int b) -{ - return dup(a, b); -} - -int -Dup1(int) -{ - return -1; -} - -void -Exit(char *stat) -{ - Updenv(); - setstatus(stat); - exits(truestatus()?"":getstatus()); -} - -int -Eintr(void) -{ - return interrupted; -} - -void -Noerror(void) -{ - interrupted = 0; -} - -int -Isatty(int fd) -{ - Dir *d1, *d2; - int ret; - - d1 = dirfstat(fd); - if(d1 == nil) - return 0; - if(strncmp(d1->name, "ptty", 4)==0){ /* fwd complaints to philw */ - free(d1); - return 1; - } - d2 = dirstat("/dev/cons"); - if(d2 == nil){ - free(d1); - return 0; - } - ret = (d1->type==d2->type&&d1->dev==d2->dev&&d1->qid.path==d2->qid.path); - free(d1); - free(d2); - return ret; -} - -void -Abort(void) -{ - pfmt(err, "aborting\n"); - flush(err); - Exit("aborting"); -} - -void -Memcpy(void *a, void *b, int32_t n) -{ - memmove(a, b, n); -} - -void* -Malloc(uint32_t n) -{ - return malloc(n); -}