diff -Nru /n/sources/plan9/sys/src/cmd/rc/code.c /sys/src/cmd/rc/code.c --- /n/sources/plan9/sys/src/cmd/rc/code.c Thu Aug 14 18:37:56 2008 +++ /sys/src/cmd/rc/code.c Wed Aug 17 00:00:00 2016 @@ -2,7 +2,7 @@ #include "io.h" #include "exec.h" #include "fns.h" -#include "getflags.h" + #define c0 t->child[0] #define c1 t->child[1] #define c2 t->child[2] diff -Nru /n/sources/plan9/sys/src/cmd/rc/exec.c /sys/src/cmd/rc/exec.c --- /n/sources/plan9/sys/src/cmd/rc/exec.c Thu Jun 13 23:21:27 2013 +++ /sys/src/cmd/rc/exec.c Wed Aug 17 00:00:00 2016 @@ -1,12 +1,15 @@ #include "rc.h" -#include "getflags.h" #include "exec.h" #include "io.h" #include "fns.h" + +char flagset[] = ""; /* anything non-nil will do */ +char *flag[NFLAG]; + /* * Start executing the given code at the given pc with the given redirection */ -char *argv0="rc"; +char *argv0; void start(code *c, int pc, var *local) @@ -113,6 +116,8 @@ newvar(char *name, var *next) { var *v = new(var); + + assert(name != nil); v->name = name; v->val = 0; v->fn = 0; @@ -121,62 +126,99 @@ v->next = next; return v; } + +/* fabricate bootstrap code (*=(argv);. /rc/lib/rcmain $*; exit) */ +static void +loadboot(code *base, int nel, char *rcmain) +{ + code *bs; + + bs = base; + bs++->i = 1; /* reference count */ + bs++->f = Xmark; /* "* = $*" */ + bs++->f = Xword; + bs++->s="*"; + bs++->f = Xassign; + bs++->f = Xmark; + bs++->f = Xmark; + bs++->f = Xword; + bs++->s="*"; + bs++->f = Xdol; + bs++->f = Xword; + bs++->s = rcmain; /* ". /rc/lib/rcmain $*" */ + bs++->f = Xword; + bs++->s="."; + bs++->f = Xsimple; + bs++->f = Xexit; /* exit */ + bs++->i = 0; /* not reached */ + if (bs > base + nel) + panic("bootstrap array too small", 0); +} + +void +usage(void) +{ + pfmt(err, "Usage: rc [-srdiIlxepvV] [-c arg] [-m command] " + "[file [arg ...]]\n"); + Exit("bad flags"); +} + /* * get command line flags, initialize keywords & traps. * get values from environment. * set $pid, $cflag, $* - * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*) + * fabricate bootstrap code and start it * start interpreting code */ - void main(int argc, char *argv[]) { code bootstrap[17]; - char num[12], *rcmain; + char num[12]; int i; - argc = getflags(argc, argv, "SsrdiIlxepvVc:1m:1[command]", 1); - if(argc==-1) - usage("[file [arg ...]]"); - if(argv[0][0]=='-') + + err = openfd(2); + ARGBEGIN { + case 'd': case 'e': case 'i': case 'l': + case 'p': case 'r': case 's': case 'v': + case 'x': case 'I': case 'V': + flag[ARGC()] = flagset; + break; + case 'c': + case 'm': + if (flag[ARGC()]) + usage(); + flag[ARGC()] = EARGF(usage()); + break; + default: + usage(); + break; + } ARGEND + if(argc < 0) + usage(); + if(argv0 == nil) + argv0 = "rc"; + if(argv0[0]=='-') /* login shell? */ flag['l'] = flagset; if(flag['I']) flag['i'] = 0; - else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset; - rcmain = flag['m']?flag['m'][0]:Rcmain; - err = openfd(2); + else if(flag['i']==0 && argc==0 && Isatty(0)) + flag['i'] = flagset; /* force interactive */ + kinit(); Trapinit(); Vinit(); inttoascii(num, mypid = getpid()); setvar("pid", newword(num, (word *)0)); - setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0) - :(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; - 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 = Xdol; - bootstrap[i++].f = Xword; - bootstrap[i++].s = rcmain; - bootstrap[i++].f = Xword; - bootstrap[i++].s="."; - bootstrap[i++].f = Xsimple; - bootstrap[i++].f = Xexit; - bootstrap[i].i = 0; + setvar("cflag", flag['c']? newword(flag['c'], (word *)0): (word *)0); + setvar("rcname", newword(argv0, (word *)0)); + + loadboot(bootstrap, nelem(bootstrap), (flag['m']? flag['m']: Rcmain)); start(bootstrap, 1, (var *)0); /* prime bootstrap argv */ pushlist(); - argv0 = strdup(argv[0]); - for(i = argc-1;i!=0;--i) pushword(argv[i]); + for(i = argc-1; i >= 0; --i) + pushword(argv[i]); for(;;){ if(flag['r']) pfnc(err, runq); @@ -186,6 +228,7 @@ dotrap(); } } + /* * Opcode routines * Arguments on stack (...) @@ -226,13 +269,14 @@ * Xpipewait * Xpopm(value) pop value from stack * Xpopredir + * Xqdol(name) concatenate variable components * 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 * Xsimple(args) run command and wait + * Xsettrue * Xsub * Xsubshell{... Xexit} execute {} in a subshell and wait * Xtrue{...} execute {} if true @@ -263,7 +307,7 @@ Xerror("can't open"); return; } - Seek(f, 0L, 2); + seek(f, 0, 2); pushredir(ROPEN, f, runq->code[runq->pc].i); runq->pc++; poplist(); @@ -692,7 +736,7 @@ copynwords(word *a, word *tail, int n) { word *v, **end; - + v = 0; end = &v; while(n-- > 0){ @@ -930,24 +974,45 @@ } void -Xerror(char *s) +pargv0(io *f) { if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s: %r\n", s); + pfmt(f, "rc: "); else - pfmt(err, "rc (%s): %s: %r\n", argv0, s); + pfmt(f, "rc (%s): ", argv0); +} + +void +hisfault(io *f) +{ + thread *t; + + for(t = runq; !t->cmdfile && t->ret != 0; t = t->ret) + ; + if(t->cmdfile && !t->iflag) + pfmt(f, "%s:%d ", t->cmdfile, t->lineno); +} + +void +Xerror(char *s) +{ + io *msg = openstr(); + + pargv0(msg); + hisfault(msg); /* capture errstr before another sys call */ + pfmt(err, "%s%s: %r\n", (char *)msg->strp, s); + closeio(msg); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); } void -Xerror1(char *s) +Xerror1(char *s) /* omit errstr */ { - if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s\n", s); - else - pfmt(err, "rc (%s): %s\n", argv0, s); + pargv0(err); + hisfault(err); + pfmt(err, "%s\n", s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); diff -Nru /n/sources/plan9/sys/src/cmd/rc/fns.h /sys/src/cmd/rc/fns.h --- /n/sources/plan9/sys/src/cmd/rc/fns.h Tue Jun 26 23:18:59 2007 +++ /sys/src/cmd/rc/fns.h Wed Aug 17 00:00:00 2016 @@ -15,7 +15,6 @@ int Opendir(char*); long Read(int, void*, long); int Readdir(int, void*, int); -long Seek(int, long, long); void Trapinit(void); void Unlink(char*); void Updenv(void); @@ -23,7 +22,7 @@ int Waitfor(int, int); long Write(int, void*, long); void addwaitpid(int); -int advance(void); +Rune advance(void); int back(int); void cleanhere(char*); void codefree(code*); @@ -37,7 +36,7 @@ void freewords(word*); void globlist(void); int havewaitpid(int); -int idchr(int); +int idchr(Rune); void inttoascii(char*, long); void kinit(void); int mapfd(int); @@ -60,8 +59,8 @@ void skipnl(void); void start(code*, int, var*); int truestatus(void); -void usage(char*); -int wordchr(int); +void usage(void); +int wordchr(Rune); void yyerror(char*); int yylex(void); int yyparse(void); diff -Nru /n/sources/plan9/sys/src/cmd/rc/getflags.c /sys/src/cmd/rc/getflags.c --- /n/sources/plan9/sys/src/cmd/rc/getflags.c Wed Jun 27 04:19:59 2007 +++ /sys/src/cmd/rc/getflags.c Thu Jan 1 00:00:00 1970 @@ -1,233 +0,0 @@ -#include "rc.h" -#include "getflags.h" -#include "fns.h" -char *flagset[] = {""}; -char **flag[NFLAG]; -char *cmdname; -static char *flagarg=""; -static void reverse(char**, char**); -static int scanflag(int, char*); -static void errn(char*, int); -static void errs(char*); -static void errc(int); -static int reason; -#define RESET 1 -#define FEWARGS 2 -#define FLAGSYN 3 -#define BADFLAG 4 -static int badflag; - -int -getflags(int argc, char *argv[], char *flags, int stop) -{ - char *s; - int i, j, c, count; - flagarg = flags; - if(cmdname==0) - cmdname = argv[0]; - - i = 1; - while(i!=argc){ - if(argv[i][0] != '-' || argv[i][1] == '\0'){ - if(stop) /* always true in rc */ - return argc; - i++; - continue; - } - s = argv[i]+1; - while(*s){ - c=*s++; - count = scanflag(c, flags); - if(count==-1) - return -1; - if(flag[c]){ reason = RESET; badflag = c; return -1; } - if(count==0){ - flag[c] = flagset; - if(*s=='\0'){ - for(j = i+1;j<=argc;j++) - argv[j-1] = argv[j]; - --argc; - } - } - else{ - if(*s=='\0'){ - for(j = i+1;j<=argc;j++) - argv[j-1] = argv[j]; - --argc; - s = argv[i]; - } - if(argc-i int havefork = 1; @@ -83,11 +81,10 @@ int pfd[2]; char *stop; char utf[UTFmax+1]; - struct io *f; + io *f, *wd; var *ifs = vlook("ifs"); word *v, *nextv; Rune r; - String *word; stop = ifs->val? ifs->val->word: ""; if(pipe(pfd)<0){ @@ -110,26 +107,26 @@ addwaitpid(pid); close(pfd[PWR]); f = openfd(pfd[PRD]); - word = s_new(); + wd = openstr(); 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); + pstr(wd, utf); /* append utf to word */ 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); + if(*(char *)wd->strp != '\0'){ + v = newword((char *)wd->strp, v); + rewind(wd); } } - if(s_len(word) > 0) - v = newword(s_to_c(word), v); - s_free(word); + if(*(char *)wd->strp != '\0') + v = newword((char *)wd->strp, v); + closeio(wd); closeio(f); Waitfor(pid, 0); /* v points to reversed arglist -- reverse it onto argv */ @@ -229,4 +226,4 @@ } addwaitpid(pid); return pid; -} +} diff -Nru /n/sources/plan9/sys/src/cmd/rc/haventfork.c /sys/src/cmd/rc/haventfork.c --- /n/sources/plan9/sys/src/cmd/rc/haventfork.c Tue May 14 22:06:03 2013 +++ /sys/src/cmd/rc/haventfork.c Wed Aug 17 00:00:00 2016 @@ -1,5 +1,4 @@ #include "rc.h" -#include "getflags.h" #include "exec.h" #include "io.h" #include "fns.h" @@ -47,7 +46,7 @@ } runq->pc++; - sprint(buf, "%d", pid); + snprint(buf, sizeof buf, "%d", pid); setvar("apid", newword(buf, (word *)0)); } diff -Nru /n/sources/plan9/sys/src/cmd/rc/io.c /sys/src/cmd/rc/io.c --- /n/sources/plan9/sys/src/cmd/rc/io.c Tue May 14 22:30:51 2013 +++ /sys/src/cmd/rc/io.c Wed Aug 17 00:00:00 2016 @@ -23,7 +23,7 @@ if(*++fmt == '\0') /* "blah%"? */ break; switch(*fmt){ - case 'c': + case 'c': /* char, not Rune */ pchr(f, va_arg(ap, int)); break; case 'd': @@ -64,7 +64,7 @@ } void -pchr(io *b, int c) +pchr(io *b, int c) /* print a char, not a Rune */ { if(b->bufp==b->ebuf) fullbuf(b, c); @@ -79,31 +79,39 @@ return *b->bufp++; } +/* + * read next utf sequence from b into buf, and convert it to Rune *r. + * return EOF or number of bytes consumed. + */ int rutf(io *b, char *buf, Rune *r) { - int n, i, c; + int i, c; c = rchr(b); - if(c == EOF) + if(c == EOF) { + buf[0] = 0; + *r = EOF; return EOF; + } *buf = c; - if(c < Runesync){ + if(c < Runeself){ /* ascii? */ + buf[1] = 0; *r = c; return 1; } - for(i = 1; (c = rchr(b)) != EOF; ){ + + /* multi-byte utf sequence */ + for(i = 1; i <= UTFmax && (c = rchr(b)) != EOF && c >= Runeself; ){ 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; - } + if(fullrune(buf, i)) + return chartorune(r, buf); } - /* at eof */ - b->bufp -= i - 1; /* consume 1 byte */ + + /* bad utf sequence: too long, or unexpected ascii or EOF */ + if (c != EOF && c < Runeself && b->bufp > b->buf) + b->bufp--; /* push back ascii */ *r = Runeerror; return runetochar(buf, r); } @@ -123,10 +131,14 @@ pwrd(io *f, char *s) { char *t; - for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break; - if(t==s || *t) + + for (t = s; *t; t++) + if (*(uchar *)t < Runeself && needsrcquote(*t)) + break; + if (t == s || *t) pquo(f, s); - else pstr(f, s); + else + pstr(f, s); } void @@ -134,12 +146,14 @@ { int n; uintptr p; + static char uphex[] = "0123456789ABCDEF"; p = (uintptr)v; - if(sizeof(uintptr) == sizeof(uvlong) && p>>32) - for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); - - for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); + if (sizeof(uintptr) == sizeof(uvlong) && p >> 32) + for (n = 60; n >= 32; n -= 4) + pchr(f, uphex[(p>>n)&0xF]); + for (n = 28; n >= 0; n -= 4) + pchr(f, uphex[(p>>n)&0xF]); } void @@ -244,6 +258,7 @@ f->fd = -1; f->bufp = f->strp = emalloc(Stralloc+1); f->ebuf = f->bufp + Stralloc; + f->output = 1; memset(f->bufp, '\0', Stralloc+1); return f; } @@ -261,6 +276,7 @@ f->fd = -1 /*open("/dev/null", 0)*/; f->bufp = f->strp = buf; f->ebuf = buf+len; + f->output = 0; Memcpy(buf, s, len); return f; } @@ -268,11 +284,13 @@ void rewind(io *io) { - if(io->fd==-1) + if(io->fd==-1) { io->bufp = io->strp; - else{ + if (io->output) + memset(io->strp, 0, io->ebuf - io->strp); + }else{ io->bufp = io->ebuf = io->buf; - Seek(io->fd, 0L, 0); + seek(io->fd, 0, 0); } } @@ -290,7 +308,9 @@ emptybuf(io *f) { int n; - if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; + + if(f->fd == -1 || (n = Read(f->fd, f->buf, NBUF))<=0) + return EOF; f->bufp = f->buf; f->ebuf = f->buf + n; return *f->bufp++; diff -Nru /n/sources/plan9/sys/src/cmd/rc/io.h /sys/src/cmd/rc/io.h --- /n/sources/plan9/sys/src/cmd/rc/io.h Tue May 14 22:30:51 2013 +++ /sys/src/cmd/rc/io.h Wed Aug 17 00:00:00 2016 @@ -5,6 +5,7 @@ int fd; uchar *bufp, *ebuf, *strp; uchar buf[NBUF]; + uchar output; /* flag */ }; io *err; @@ -13,6 +14,7 @@ void pchr(io*, int); int rchr(io*); int rutf(io*, char*, Rune*); +void rewind(io*); void closeio(io*); void flush(io*); int fullbuf(io*, int); diff -Nru /n/sources/plan9/sys/src/cmd/rc/lex.c /sys/src/cmd/rc/lex.c --- /n/sources/plan9/sys/src/cmd/rc/lex.c Thu Jun 13 23:22:59 2013 +++ /sys/src/cmd/rc/lex.c Wed Aug 17 00:00:00 2016 @@ -1,35 +1,43 @@ #include "rc.h" #include "exec.h" #include "io.h" -#include "getflags.h" #include "fns.h" -int getnext(void); + +Rune getnext(void); int -wordchr(int c) +wordchr(Rune c) /* is c in the alphabet of words (non-delimiters)? */ { - return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF; + return c != EOF && + (c >= Runeself || strchr("\n \t#;&|^$=`'{}()<>", c) == nil); } +/* + * is c in the alphabet of identifiers? as in the c compiler, treat + * non-ascii as alphabetic. + */ int -idchr(int c) +idchr(Rune c) { /* * Formerly: * return 'a'<=c && c<='z' || 'A'<=c && c<='Z' || '0'<=c && c<='9' * || c=='_' || c=='*'; */ - return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); + return c != EOF && (c >= Runeself || + c > ' ' && + strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c) == nil); } -int future = EOF; + +Rune future = EOF; int doprompt = 1; -int inquote; -int incomm; +int inquote; /* are we processing a quoted word ('...')? */ +int incomm; /* are we ignoring input in a comment (#...\n)? */ /* * Look ahead in the input stream */ -int +Rune nextc(void) { if(future==EOF) @@ -40,23 +48,26 @@ * Consume the lookahead character. */ -int +Rune advance(void) { - int c = nextc(); + Rune c = nextc(); + lastc = future; future = EOF; return c; } /* * read a character from the input stream - */ + */ -int +Rune getnext(void) { - int c; - static int peekc = EOF; + Rune c; + char buf[UTFmax+1]; + static Rune peekc = EOF; + if(peekc!=EOF){ c = peekc; peekc = EOF; @@ -66,9 +77,9 @@ return EOF; if(doprompt) pprompt(); - c = rchr(runq->cmdfd); + rutf(runq->cmdfd, buf, &c); if(!inquote && c=='\\'){ - c = rchr(runq->cmdfd); + rutf(runq->cmdfd, buf, &c); if(c=='\n' && !incomm){ /* don't continue a comment */ doprompt = 1; c=' '; @@ -105,7 +116,8 @@ void skipwhite(void) { - int c; + Rune c; + for(;;){ c = nextc(); /* Why did this used to be if(!inquote && c=='#') ?? */ @@ -129,18 +141,22 @@ void skipnl(void) { - int c; - for(;;){ + Rune c, c0; + + for(c0 = nextc(); ; c0 = c){ skipwhite(); c = nextc(); + if(c != c0) + lastword = 0; /* change of whitespace or c is not ws */ if(c!='\n') return; + lastword = 0; /* new line; continue */ advance(); } } int -nextis(int c) +nextis(Rune c) { if(nextc()==c){ advance(); @@ -150,38 +166,16 @@ } char* -addtok(char *p, int val) +addutf(char *p, Rune c) { if(p==0) return 0; - if(p >= &tok[NTOK]){ + if(p >= &tok[NTOK-1-UTFmax*2]){ *p = 0; yyerror("token buffer too short"); return 0; } - *p++=val; - return p; -} - -char* -addutf(char *p, int c) -{ - uchar b, m; - int i; - - p = addtok(p, c); /* 1-byte UTF runes are special */ - if(c < Runeself) - return p; - - m = 0xc0; - b = 0x80; - for(i=1; i < UTFmax; i++){ - if((c&m) == b) - break; - p = addtok(p, advance()); - b = m; - m = (m >> 1)|0x80; - } + p += runetochar(p, &c); return p; } @@ -191,16 +185,17 @@ int yylex(void) { - int c, d = nextc(); + Rune c, d = nextc(); char *w = tok; struct tree *t; + yylval.tree = 0; /* - * Embarassing sneakiness: if the last token read was a quoted or unquoted - * WORD then we alter the meaning of what follows. If the next character - * is `(', we return SUB (a subscript paren) and consume the `('. Otherwise, - * if the next character is the first character of a simple or compound word, - * we insert a `^' before it. + * Embarrassing sneakiness: if the last token read was a quoted or + * unquoted WORD then we alter the meaning of what follows. If the + * next character is `(', we return SUB (a subscript paren) and + * consume the `('. Otherwise, if the next character is the first + * character of a simple or compound word, we insert a `^' before it. */ if(lastword){ lastword = 0; @@ -214,7 +209,6 @@ return '^'; } } - inquote = 0; skipwhite(); switch(c = advance()){ case EOF: @@ -357,23 +351,22 @@ t = token(tok, WORD); t->quoted = 1; yylval.tree = t; + inquote = 0; return t->type; } if(!wordchr(c)){ lastdol = 0; - tok[0] = c; - tok[1]='\0'; + addutf(tok, c); return c; } for(;;){ if(c=='*' || c=='[' || c=='?' || c==GLOB) - w = addtok(w, GLOB); + w = addutf(w, GLOB); w = addutf(w, c); c = nextc(); if(lastdol?!idchr(c):!wordchr(c)) break; advance(); } - lastword = 1; lastdol = 0; if(w!=0) diff -Nru /n/sources/plan9/sys/src/cmd/rc/mkfile /sys/src/cmd/rc/mkfile --- /n/sources/plan9/sys/src/cmd/rc/mkfile Tue Jun 26 20:46:37 2007 +++ /sys/src/cmd/rc/mkfile Wed Aug 17 00:00:00 2016 @@ -4,7 +4,6 @@ COMMONOFILES=\ code.$O\ exec.$O\ - getflags.$O\ glob.$O\ here.$O\ io.$O\ @@ -29,7 +28,6 @@ io.h\ exec.h\ fns.h\ - getflags.h\ YFILES=syn.y diff -Nru /n/sources/plan9/sys/src/cmd/rc/pfnc.c /sys/src/cmd/rc/pfnc.c --- /n/sources/plan9/sys/src/cmd/rc/pfnc.c Thu Jun 13 23:22:17 2013 +++ /sys/src/cmd/rc/pfnc.c Wed Aug 17 00:00:00 2016 @@ -63,14 +63,14 @@ list *a; pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); - for (i = 0; fname[i].f; i++) + for (i = 0; fname[i].f; i++) if (fname[i].f == fn) { pstr(fd, fname[i].name); break; } 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 -Nru /n/sources/plan9/sys/src/cmd/rc/plan9.c /sys/src/cmd/rc/plan9.c --- /n/sources/plan9/sys/src/cmd/rc/plan9.c Thu Jun 13 23:21:10 2013 +++ /sys/src/cmd/rc/plan9.c Wed Aug 17 00:00:00 2016 @@ -7,11 +7,6 @@ #include "exec.h" #include "io.h" #include "fns.h" -#include "getflags.h" - -enum { - Maxenvname = 256, /* undocumented limit */ -}; char *Signame[] = { "sigexit", "sighup", "sigint", "sigquit", @@ -63,27 +58,28 @@ break; case 2: arg = 0; - for(s = runq->argv->words->next->word;*s;s++) switch(*s){ - default: - goto Usage; - case 'n': - arg|=RFNAMEG; break; - case 'N': - arg|=RFCNAMEG; - break; - case 'm': - arg|=RFNOMNT; break; - case 'e': - arg|=RFENVG; break; - case 'E': - arg|=RFCENVG; break; - case 's': - arg|=RFNOTEG; break; - case 'f': - arg|=RFFDG; break; - case 'F': - arg|=RFCFDG; break; - } + for(s = runq->argv->words->next->word;*s;s++) + switch(*s){ + default: + goto Usage; + case 'n': + arg|=RFNAMEG; break; + case 'N': + arg|=RFCNAMEG; + break; + case 'm': + arg|=RFNOMNT; break; + case 'e': + arg|=RFENVG; break; + case 'E': + arg|=RFCENVG; break; + case 's': + arg|=RFNOTEG; break; + case 'f': + arg|=RFFDG; break; + case 'F': + arg|=RFCFDG; break; + } break; default: Usage: @@ -101,12 +97,40 @@ poplist(); } +int +openenv(char *shortname) +{ + int f; + io *envname; + + envname = openstr(); + pfmt(envname, "/env/%s", shortname); + f = open((char *)envname->strp, OREAD); + closeio(envname); + return f; +} + +int +createenv(char *pfx, char *shortname) +{ + int f; + io *envname; + + envname = openstr(); + pfmt(envname, "/env/%s%s", pfx, shortname); + f = Creat((char *)envname->strp); + if (f < 0) + pfmt(err, "rc: can't create %s: %r\n", (char *)envname->strp); + closeio(envname); + return f; +} + void Vinit(void) { int dir, f, len, i, n, nent; - char *buf, *s; - char envname[Maxenvname]; + char *buf, *s, *name; + var *namevar; word *val; Dir *ent; @@ -116,52 +140,52 @@ return; } ent = nil; - for(;;){ - nent = dirread(dir, &ent); - if(nent <= 0) - break; + while ((nent = dirread(dir, &ent)) > 0) { for(i = 0; i=0){ - buf = emalloc(len+1); - n = readn(f, buf, len); - if (n <= 0) - buf[0] = '\0'; - else - buf[n] = '\0'; - 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); - } + name = ent[i].name; + if(len <= 0 || strncmp(name, "fn#", 3) == 0) + continue; + if((f = openenv(name)) < 0) + continue; + buf = emalloc(len+1); + n = readn(f, buf, len); + if (n <= 0) + buf[0] = '\0'; + else + buf[n] = '\0'; + 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(name, val); + namevar = vlook(name); + assert(namevar != nil); + namevar->changed = 0; + close(f); + efree(buf); } free(ent); } close(dir); } + int envdir; void Xrdfn(void) { - int f, len; + int f; Dir *e; - char envname[Maxenvname]; static Dir *ent, *allocent; static int nent; @@ -176,10 +200,8 @@ 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, 0))>=0){ + if(e->length && strncmp(e->name, "fn#", 3)==0){ + if((f = openenv(e->name)) >= 0){ execcmds(openfd(f)); return; } @@ -189,6 +211,7 @@ close(envdir); Xreturn(); } + union code rdfns[4]; void @@ -222,6 +245,9 @@ return 0; while((w = wait()) != nil){ + /* this would otherwise go unreported by rc */ + if(strstr(w->msg, "error in demand load") != nil) + pfmt(err, "rc: %s\n", w->msg); delwaitpid(w->pid); if(w->pid==pid){ setstatus(w->msg); @@ -254,27 +280,20 @@ void addenv(var *v) { - char envname[Maxenvname]; 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{ + if((f = createenv("", v->name)) >= 0) { for(w = v->val;w;w = w->next) - write(f, w->word, strlen(w->word)+1L); + write(f, w->word, strlen(w->word)+1); 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((f = createenv("fn#", v->name)) >= 0) { if(v->fn){ fd = openfd(f); pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s); @@ -339,43 +358,48 @@ Execute(word *args, word *path) { char **argv = mkargv(args); - char file[1024], errstr[1024]; + char file[1024], errstr[ERRMAX+1]; int nc; Updenv(); errstr[0] = '\0'; 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 >= sizeof file - 1){ /* 1 for / */ + werrstr("path component too long"); + continue; } + strcpy(file, path->word); + if(file[0]){ + strcat(file, "/"); + nc++; + } + if(nc + strlen(argv[1]) >= sizeof file){ + werrstr("command name too long"); + continue; + } + strcat(file, argv[1]); + exec(file, argv+1); + /* + * 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 or + * i/o failure, stop searching and print the reason for failure. + */ + rerrstr(errstr, sizeof errstr); + if (strstr(errstr, " allocat") != nil || + strstr(errstr, " full") != nil || + strstr(errstr, "i/o error") != nil) + break; } + if(errstr[0] == '\0') /* pick up any werrstr "too long"s */ + rerrstr(errstr, sizeof errstr); pfmt(err, "%s: %s\n", argv[1], errstr); efree((char *)argv); } -#define NDIR 256 /* shoud be a better way */ + +#define NDIR 256 /* should be a better way */ int Globsize(char *p) @@ -438,7 +462,7 @@ * onlydirs is advisory -- it means you only * need to return the directories. it's okay to * return files too (e.g., on unix where you can't - * tell during the readdir), but that just makes + * tell during the readdir), but that just makes * the globber work harder. */ int @@ -458,7 +482,7 @@ n = trimdirs(dir[f].dbuf, n); if(n == 0) goto Again; - } + } dir[f].n = n; }else dir[f].n = 0; @@ -482,24 +506,29 @@ } close(f); } + int interrupted = 0; + void notifyf(void*, char *s) { int i; - for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ - if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; - goto Out; - } + + for (i = 0; syssigname[i]; i++) + if (strncmp(s, syssigname[i], strlen(syssigname[i])) == 0) { + if (strncmp(s, "sys: ", 5) != 0) + interrupted = 1; + goto Out; + } pfmt(err, "rc: note: %s\n", s); noted(NDFLT); return; Out: - if(strcmp(s, "interrupt")!=0 || trap[i]==0){ + if (strcmp(s, "interrupt") != 0 || trap[i] == 0) { trap[i]++; ntrap++; } - if(ntrap>=32){ /* rc is probably in a trap loop */ + if (ntrap >= 32) { /* rc is probably in a trap loop */ pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); abort(); } @@ -530,12 +559,6 @@ return read(fd, buf, cnt); } -long -Seek(int fd, long cnt, long whence) -{ - return seek(fd, cnt, whence); -} - int Executable(char *file) { @@ -553,7 +576,7 @@ int Creat(char *file) { - return create(file, 1, 0666L); + return create(file, 1, 0666); } int @@ -640,7 +663,7 @@ delwaitpid(int pid) { int r, w; - + for(r=w=0; r= '0' && (c) <= '9') /* NB: unsafe macro */ + #ifndef Unix /* plan 9 */ #include #include +#pragma incomplete word +#pragma incomplete io + +/* unix compatibility */ +#define unixclsexec(wdirfd) + #define NSIG 32 #define SIGINT 2 #define SIGQUIT 3 - -#define fcntl(fd, op, arg) /* unix compatibility */ -#define F_SETFD -#define FD_CLOEXEC #else #include "unix.h" #endif -#ifndef ERRMAX -#define ERRMAX 128 -#endif - #define YYMAXDEPTH 500 #ifndef YYPREFIX #ifndef PAREN @@ -30,21 +40,6 @@ #endif #endif -typedef struct tree tree; -typedef struct word word; -typedef struct io io; -typedef union code code; -typedef struct var var; -typedef struct list list; -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 */ @@ -147,5 +142,10 @@ */ int ndot; char *getstatus(void); -int lastc; +Rune lastc; int lastword; + +#define NFLAG 128 /* limited to ascii */ + +extern char *flag[NFLAG]; +extern char flagset[]; diff -Nru /n/sources/plan9/sys/src/cmd/rc/rune.c /sys/src/cmd/rc/rune.c --- /n/sources/plan9/sys/src/cmd/rc/rune.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/rc/rune.c Wed Aug 17 00:00:00 2016 @@ -0,0 +1,165 @@ +#include "rc.h" + +#define Bit(i) (7-(i)) +/* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */ +#define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF) +/* 0000 0000 0000 0111 1111 1111 */ +#define RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1) + +enum +{ + Bitx = Bit(1), + + Tx = T(1), /* 1000 0000 */ + Rune1 = (1<<(Bit(0)+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ + + Maskx = (1< T1 + * 00080-007FF => T2 Tx + * 00800-0FFFF => T3 Tx Tx + * 10000-10FFFF => T4 Tx Tx Tx + */ + + c[0] = *(uchar*)(str); + if(c[0] < Tx){ + *rune = c[0]; + return 1; + } + l = c[0]; + + for(i = 1; i < UTFmax; i++) { + c[i] = *(uchar*)(str+i); + c[i] ^= Tx; + if(c[i] & Testx) + goto bad; + l = (l << Bitx) | c[i]; + if(c[0] < T(i + 2)) { + l &= RuneX(i + 1); + if(i == 1) { + if(c[0] < T(2) || l <= Rune1) + goto bad; + } else if(l <= RuneX(i) || l > Runemax) + goto bad; + if (i == 2 && SurrogateMin <= l && l <= SurrogateMax) + goto bad; + *rune = l; + return i + 1; + } + } + + /* + * bad decoding + */ +bad: + *rune = Bad; + return 1; +} + +int +runetochar(char *str, Rune *rune) +{ + int i, j; + Rune c; + + c = *rune; + if(c <= Rune1) { + str[0] = c; + return 1; + } + + /* + * one character sequence + * 00000-0007F => 00-7F + * two character sequence + * 0080-07FF => T2 Tx + * three character sequence + * 0800-FFFF => T3 Tx Tx + * four character sequence (21-bit value) + * 10000-1FFFFF => T4 Tx Tx Tx + * If the Rune is out of range or a surrogate half, + * convert it to the error rune. + * Do this test when i==3 because the error rune encodes to three bytes. + * Doing it earlier would duplicate work, since an out of range + * Rune wouldn't have fit in one or two bytes. + */ + for(i = 2; i < UTFmax + 1; i++){ + if(i == 3){ + if(c > Runemax) + c = Runeerror; + if(SurrogateMin <= c && c <= SurrogateMax) + c = Runeerror; + } + if (c <= RuneX(i) || i == UTFmax ) { + str[0] = T(i) | (c >> (i - 1)*Bitx); + for(j = 1; j < i; j++) + str[j] = Tx | ((c >> (i - j - 1)*Bitx) & Maskx); + return i; + } + } + return UTFmax; +} + +int +runelen(long c) +{ + Rune rune; + char str[10]; + + rune = c; + return runetochar(str, &rune); +} + +int +runenlen(Rune *r, int nrune) +{ + int nb, i; + Rune c; + + nb = 0; + while(nrune--) { + c = *r++; + if(c <= Rune1){ + nb++; + } else { + for(i = 2; i < UTFmax + 1; i++) + if(c <= RuneX(i) || i == UTFmax){ + nb += i; + break; + } + } + } + return nb; +} + +int +fullrune(char *str, int n) +{ + int i; + Rune c; + + if(n <= 0) + return 0; + c = *(uchar*)str; + if(c < Tx) + return 1; + for(i = 3; i < UTFmax + 1; i++) + if(c < T(i)) + return n >= i - 1; + return n >= UTFmax; +} diff -Nru /n/sources/plan9/sys/src/cmd/rc/simple.c /sys/src/cmd/rc/simple.c --- /n/sources/plan9/sys/src/cmd/rc/simple.c Thu Jun 13 23:21:01 2013 +++ /sys/src/cmd/rc/simple.c Wed Aug 17 00:00:00 2016 @@ -2,7 +2,6 @@ * Maybe `simple' is a misnomer. */ #include "rc.h" -#include "getflags.h" #include "exec.h" #include "io.h" #include "fns.h" @@ -10,7 +9,8 @@ * Search through the following code to see if we're just going to exit. */ int -exitnext(void){ +exitnext(void) +{ union code *c=&runq->code[runq->pc]; while(c->f==Xpopredir) c++; return c->f==Xexit; @@ -146,7 +146,7 @@ if(wdirfd==-2) /* try only once */ wdirfd = open("/dev/wdir", OWRITE|OCEXEC); if(wdirfd>=0) { - fcntl(wdirfd, F_SETFD, FD_CLOEXEC); + unixclsexec(wdirfd); write(wdirfd, word, strlen(word)); } } @@ -264,15 +264,6 @@ } 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) { redir *rp; @@ -447,7 +438,8 @@ } void -execwhatis(void){ /* mildly wrong -- should fork before writing */ +execwhatis(void) /* mildly wrong -- should fork before writing */ +{ word *a, *b, *path; var *v; struct builtin *bp; diff -Nru /n/sources/plan9/sys/src/cmd/rc/syn.y /sys/src/cmd/rc/syn.y --- /n/sources/plan9/sys/src/cmd/rc/syn.y Sun Dec 12 01:11:23 1999 +++ /sys/src/cmd/rc/syn.y Wed Aug 17 00:00:00 2016 @@ -45,7 +45,7 @@ | IF NOT {skipnl();} cmd {$$=mung1($2, $4);} | FOR '(' word IN words ')' {skipnl();} cmd /* - * if ``words'' is nil, we need a tree element to distinguish between + * if ``words'' is nil, we need a tree element to distinguish between * for(i in ) and for(i), the former being a loop over the empty set * and the latter being the implicit argument loop. so if $5 is nil * (the empty set), we represent it as "()". don't parenthesize non-nil @@ -73,7 +73,7 @@ simple: first | simple word {$$=tree2(ARGLIST, $1, $2);} | simple redir {$$=tree2(ARGLIST, $1, $2);} -first: comword +first: comword | first '^' word {$$=tree2('^', $1, $3);} word: keyword {lastword=1; $1->type=WORD;} | comword diff -Nru /n/sources/plan9/sys/src/cmd/rc/tree.c /sys/src/cmd/rc/tree.c --- /n/sources/plan9/sys/src/cmd/rc/tree.c Tue Jun 26 22:52:20 2007 +++ /sys/src/cmd/rc/tree.c Wed Aug 17 00:00:00 2016 @@ -138,7 +138,7 @@ freetree(tree *p) { if(p==0) - return; + return; freetree(p->child[0]); freetree(p->child[1]); freetree(p->child[2]); diff -Nru /n/sources/plan9/sys/src/cmd/rc/unix.c /sys/src/cmd/rc/unix.c --- /n/sources/plan9/sys/src/cmd/rc/unix.c Fri Mar 1 22:25:23 2013 +++ /sys/src/cmd/rc/unix.c Wed Aug 17 00:00:00 2016 @@ -6,7 +6,6 @@ #include "rc.h" #include "io.h" #include "exec.h" -#include "getflags.h" #include char *Rcmain = "/usr/lib/rcmain"; @@ -431,11 +430,6 @@ { return read(fd, buf, cnt); } -Seek(fd, cnt, whence) -long cnt; -{ - return lseek(fd, cnt, whence); -} Executable(file) char *file; { @@ -489,6 +483,15 @@ abort(); } +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; +} + void execumask(void) /* wrong -- should fork before writing */ { @@ -549,6 +552,12 @@ rfork(int bits) { return fork(); +} + +void +unixclsexec(int fd) +{ + fcntl(fd, F_SETFD, FD_CLOEXEC); } int *waitpids; diff -Nru /n/sources/plan9/sys/src/cmd/rc/unix.h /sys/src/cmd/rc/unix.h --- /n/sources/plan9/sys/src/cmd/rc/unix.h Fri Mar 1 22:55:48 2013 +++ /sys/src/cmd/rc/unix.h Wed Aug 17 00:00:00 2016 @@ -1,3 +1,5 @@ +/* mostly plan 9 compatibility */ + #undef _BSD_EXTENSION /* avoid multiple def'n if predefined */ #undef _PLAN9_SOURCE #undef _POSIX_SOURCE @@ -22,17 +24,29 @@ #define NSIG 32 #endif -/* plan 9 compatibility */ #define RFPROC 1 #define RFFDG 1 #define RFNOTEG 1 -#define uintptr uintptr_t +#define OREAD O_RDONLY +#define OWRITE O_WRONLY +#define ORDWR O_RDWR +#define OCEXEC 0 -char *strdup(const char *); +#define ERRMAX 128 +#define uintptr uintptr_t #define nil ((void*)0) +#define assert(cond) +#define seek lseek +#define print printf +#define fprint fprintf +#define snprint snprintf + +char *strdup(const char *); +void unixclsexec(int); + /* in case uchar, etc. are built-in types */ #define uchar _fmtuchar #define ushort _fmtushort @@ -47,7 +61,52 @@ typedef unsigned long ulong; typedef unsigned long long uvlong; -#define OREAD O_RDONLY -#define OWRITE O_WRONLY -#define ORDWR O_RDWR -#define OCEXEC 0 +typedef ulong Rune; + +enum +{ + UTFmax = 4, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0xFFFD, /* decoding error in UTF */ + Runemax = 0x10FFFF, /* 21-bit rune */ + Runemask = 0x1FFFFF, /* bits used by runes (see grep) */ +}; + +/* + * rune routines + */ +extern int runetochar(char*, Rune*); +extern int chartorune(Rune*, char*); +extern int runelen(long); +extern int runenlen(Rune*, int); +extern int fullrune(char*, int); +extern int utflen(char*); +extern int utfnlen(char*, long); +extern char* utfrune(char*, long); +extern char* utfrrune(char*, long); +extern char* utfutf(char*, char*); +extern char* utfecpy(char*, char*, char*); + +extern char *argv0; +#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ + argv[0] && argv[0][0]=='-' && argv[0][1];\ + argc--, argv++) {\ + char *_args, *_argt;\ + Rune _argc;\ + _args = &argv[0][1];\ + if(_args[0]=='-' && _args[1]==0){\ + argc--; argv++; break;\ + }\ + _argc = 0;\ + while(*_args && (_args += chartorune(&_argc, _args)))\ + switch(_argc) +#define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); +#define ARGF() (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) +#define EARGF(x) (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) + +#define ARGC() _argc + +#define nelem(x) (sizeof(x)/sizeof((x)[0])) diff -Nru /n/sources/plan9/sys/src/cmd/rc/utfrune.c /sys/src/cmd/rc/utfrune.c --- /n/sources/plan9/sys/src/cmd/rc/utfrune.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/rc/utfrune.c Wed Aug 17 00:00:00 2016 @@ -0,0 +1,28 @@ +#include "rc.h" + +char* +utfrune(char *s, long c) +{ + long c1; + Rune r; + int n; + + if(c < Runesync) /* not part of utf sequence */ + return strchr(s, c); + + for(;;) { + c1 = *(uchar*)s; + if(c1 < Runeself) { /* one byte rune */ + if(c1 == 0) + return 0; + if(c1 == c) + return s; + s++; + continue; + } + n = chartorune(&r, s); + if(r == c) + return s; + s += n; + } +} diff -Nru /n/sources/plan9/sys/src/cmd/rc/utfutf.c /sys/src/cmd/rc/utfutf.c --- /n/sources/plan9/sys/src/cmd/rc/utfutf.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/rc/utfutf.c Wed Aug 17 00:00:00 2016 @@ -0,0 +1,24 @@ +#include "rc.h" + +/* + * Return pointer to first occurrence of s2 in s1, + * 0 if none + */ +char* +utfutf(char *s1, char *s2) +{ + char *p; + long f, n1, n2; + Rune r; + + n1 = chartorune(&r, s2); + f = r; + if(f <= Runesync) /* represents self */ + return strstr(s1, s2); + + n2 = strlen(s2); + for(p=s1; p=utfrune(p, f); p+=n1) + if(strncmp(p, s2, n2) == 0) + return p; + return 0; +} diff -Nru /n/sources/plan9/sys/src/cmd/rc/var.c /sys/src/cmd/rc/var.c --- /n/sources/plan9/sys/src/cmd/rc/var.c Thu Jun 13 23:22:45 2013 +++ /sys/src/cmd/rc/var.c Wed Aug 17 00:00:00 2016 @@ -67,7 +67,10 @@ { int h = hash(name, NVAR); var *v; - for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return 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]); } @@ -75,9 +78,11 @@ vlook(char *name) { var *v; - if(runq) - for(v = runq->local;v;v = v->next) - if(strcmp(v->name, name)==0) return v; + + if (runq) + for (v = runq->local; v; v = v->next) + if (strcmp(v->name, name) == 0) + return v; return gvlook(name); } diff -Nru /n/sources/plan9/sys/src/cmd/rc/win32.c /sys/src/cmd/rc/win32.c --- /n/sources/plan9/sys/src/cmd/rc/win32.c Fri Mar 1 19:53:47 2013 +++ /sys/src/cmd/rc/win32.c Wed Aug 17 00:00:00 2016 @@ -7,7 +7,6 @@ #include "exec.h" #include "io.h" #include "fns.h" -#include "getflags.h" char *Signame[] = { "sigexit", "sighup", "sigint", "sigquit", "sigalrm", "sigkill", "sigfpe", "sigterm", @@ -456,12 +455,6 @@ Read(int fd, void *buf, long cnt) { return read(fd, buf, cnt); -} - -long -Seek(int fd, long cnt, long whence) -{ - return seek(fd, cnt, whence); } int