1 #define INFERNO_KEEPENVIRON 2 #include <lib9.h> 3 4 #define Lock Rclock 5 #define Ref Rcref 6 7 typedef union Code Code; 8 typedef struct Tree Tree; 9 typedef struct Thread Thread; 10 typedef struct Word Word; 11 typedef struct Var Var; 12 typedef struct List List; 13 typedef struct Redir Redir; 14 typedef struct Io Io; 15 typedef struct Here Here; 16 typedef struct Ref Ref; 17 typedef struct Lock Lock; 18 typedef struct Direntry Direntry; 19 20 #define EOF (-1) 21 #define NBUF 512 22 23 /* values for Tree->rtype */ 24 #define APPEND 1 25 #define WRITE 2 26 #define READ 3 27 #define HERE 4 28 #define DUPFD 5 29 #define CLOSE 6 30 31 /* 32 * redir types 33 */ 34 #define ROPEN 1 /* dup2(from, to); close(from); */ 35 #define RDUP 2 /* dup2(from, to); */ 36 #define RCLOSE 3 /* close(from); */ 37 38 #define NSTATUS 64 /* length of status (from plan 9) */ 39 40 #define IWS 0x01 /* inter word seperator when word lists are stored in env variables */ 41 42 /* 43 * Glob character escape in strings: 44 * In a string, GLOB must be followed by *?[ or GLOB. 45 * GLOB* matches any string 46 * GLOB? matches any single character 47 * GLOB[...] matches anything in the brackets 48 * GLOBGLOB matches GLOB 49 */ 50 #define GLOB ((char)0x02) 51 52 /* 53 * The first word of any code vector is a reference count. 54 * Always create a new reference to a code vector by calling codecopy(.). 55 * Always call codefree(.) when deleting a reference. 56 */ 57 union Code { 58 void (*f)(void); 59 int i; 60 char *s; 61 }; 62 63 64 struct Tree 65 { 66 int type; 67 int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ 68 char *str; 69 int quoted; 70 int iskw; 71 Tree *child[3]; 72 Tree *next; 73 }; 74 75 struct Thread 76 { 77 Code *code; /* code for this thread */ 78 int pc; /* code[pc] is the next instruction */ 79 List *argv; /* argument stack */ 80 Redir *redir; /* redirection stack */ 81 Redir *startredir; /* redir inheritance point */ 82 Var *local; /* list of local variables */ 83 char *cmdfile; /* file name in Xrdcmd */ 84 Io *cmdfd; /* file descriptor for Xrdcmd */ 85 int iflast; /* static `if not' checking */ 86 int eof; /* is cmdfd at eof? */ 87 int iflag; /* interactive? */ 88 int lineno; /* linenumber */ 89 int pid; /* process for Xpipewait to wait for */ 90 char status[NSTATUS]; /* status for Xpipewait */ 91 Tree *treenodes; /* tree nodes created by this process */ 92 Thread *ret; /* who continues when this finishes */ 93 }; 94 95 struct Io 96 { 97 int fd; 98 char *bufp; 99 char *ebuf; 100 char *strp; 101 char buf[NBUF]; 102 }; 103 104 struct Var 105 { 106 char *name; /* ascii name */ 107 Word *val; /* value */ 108 int changed; 109 Code *fn; /* pointer to function's code vector */ 110 int fnchanged; 111 int pc; /* pc of start of function */ 112 Var *next; /* next on hash or local list */ 113 }; 114 115 struct Word 116 { 117 char *word; 118 Word *next; 119 }; 120 121 struct List 122 { 123 Word *words; 124 List *next; 125 }; 126 127 struct Redir 128 { 129 char type; /* what to do */ 130 short from, to; /* what to do it to */ 131 Redir *next; /* what else to do (reverse order) */ 132 }; 133 134 struct Here{ 135 Tree *tag; 136 char *name; 137 Here *next; 138 }; 139 140 struct Lock { 141 int val; 142 }; 143 144 struct Ref 145 { 146 Lock lk; 147 int ref; 148 }; 149 150 struct Direntry 151 { 152 int isdir; 153 char *name; 154 }; 155 156 /* main.c */ 157 void start(Code *c, int pc, Var *local); 158 159 /* lex.c */ 160 void yyerror(char*); 161 int yylex(void); 162 int yyparse(void); 163 int wordchr(int); 164 int idchr(int); 165 166 /* code.c */ 167 int compile(Tree*); 168 Code *codecopy(Code*); 169 void codefree(Code*); 170 void cleanhere(char *f); 171 172 void skipnl(void); 173 174 void panic(char*, int); 175 176 /* var.c */ 177 void kinit(void); 178 void vinit(void); 179 Var *vlook(char*); 180 Var *gvlook(char*); 181 Var *newvar(char*, Var*); 182 void setvar(char*, Word*); 183 void updenv(void); 184 void kenter(int type, char *name); 185 186 /* glob.c */ 187 void deglob(char*); 188 void globlist(void); 189 int match(char *s, char *p, int stop); 190 191 /* main.c */ 192 void setstatus(char *s); 193 char *getstatus(void); 194 int truestatus(void); 195 void execcmds(Io*); 196 char *concstatus(char *s, char *t); 197 char **procargv(char*, char*, char*, char*, Word *w); 198 199 void freewords(Word*); 200 201 /* tree.c */ 202 Tree *newtree(void); 203 Tree *token(char*, int), *klook(char*), *tree1(int, Tree*); 204 Tree *tree2(int, Tree*, Tree*), *tree3(int, Tree*, Tree*, Tree*); 205 Tree *mung1(Tree*, Tree*), *mung2(Tree*, Tree*, Tree*); 206 Tree *mung3(Tree*, Tree*, Tree*, Tree*), *epimung(Tree*, Tree*); 207 Tree *simplemung(Tree*), *heredoc(Tree*); 208 void freetree(Tree*); 209 void freenodes(void); 210 211 /* here.c */ 212 Tree *heredoc(Tree *tag); 213 214 /* exec.c */ 215 extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void); 216 extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqdol(void), Xdup(void); 217 extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); 218 extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); 219 extern void Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); 220 extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void); 221 extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); 222 extern void Xrdcmds(void), Xwastrue(void), Xif(void), Xifnot(void), Xpipewait(void); 223 extern void Xdelhere(void), Xpopredir(void), Xsub(void), Xeflag(void), Xsettrue(void); 224 extern void Xerror(char*), Xperror(char*); 225 226 /* word.c */ 227 Word *newword(char*, Word*); 228 void pushlist(void); 229 void poplist(void); 230 void pushword(char*); 231 void popword(void); 232 int count(Word*); 233 Word *copywords(Word*, Word*); 234 void pushredir(int, int, int); 235 void turfredir(void); 236 char *list2str(Word*); 237 void freelist(Word*); 238 Word *conclist(Word*, Word*, Word*); 239 Word *subwords(Word*, int, Word*, Word*); 240 241 /* io.c */ 242 #define pchr(b, c) if((b)->bufp==(b)->ebuf)fullbuf((b), (c));else (*(b)->bufp++=(c)) 243 #define rchr(b) ((b)->bufp==(b)->ebuf?emptybuf(b):(*(b)->bufp++&0xff)) 244 245 Io *openfd(int), *openstr(void), *opencore(char*, int); 246 int emptybuf(Io*); 247 void closeio(Io*); 248 void flush(Io*); 249 int fullbuf(Io*, int); 250 251 void pfmt(Io*, char*, ...); 252 void perr(Io*); 253 void pstr(Io*, char*); 254 void pfnc(Io*, Thread*); 255 256 void pprompt(void); 257 258 /* trap.c */ 259 void dotrap(void); 260 void dointr(void); 261 262 void waitfor(uint); 263 264 /* nt.c */ 265 266 Direntry* readdirect(char*); 267 void fatal(char*, ...); 268 uint proc(char**, int, int, int); 269 int procwait(uint); 270 int refinc(Ref*); 271 int refdec(Ref*); 272 int pipe(int*); 273 274 /* 275 * onebyte(c), twobyte(c), threebyte(c) 276 * Is c the first character of a one- two- or three-byte utf sequence? 277 */ 278 #define onebyte(c) ((c&0x80)==0x00) 279 #define twobyte(c) ((c&0xe0)==0xc0) 280 #define threebyte(c) ((c&0xf0)==0xe0) 281 282 #define new(type) ((type *)malloc(sizeof(type))) 283 284 285 extern Tree *cmdtree; 286 extern Thread *runq; 287 extern Io *err; 288 extern int flag[256]; 289 extern int doprompt; 290 extern char *promptstr; 291 extern int ndot; 292 extern int nerror; 293 extern Code *codebuf; 294 extern int eflagok; 295 extern int interrupted; 296 extern Ref ntrap; 297