1 | #include <stdlib.h>
|
---|
2 | #include <string.h>
|
---|
3 | #include <unistd.h>
|
---|
4 | #include <fcntl.h>
|
---|
5 |
|
---|
6 | /* Need a way to have void used for ANSI, nothing for K&R. */
|
---|
7 | #ifndef _ANSI
|
---|
8 | #undef _VOID
|
---|
9 | #define _VOID
|
---|
10 | #endif
|
---|
11 |
|
---|
12 | /* -------- sh.h -------- */
|
---|
13 | /*
|
---|
14 | * shell
|
---|
15 | */
|
---|
16 |
|
---|
17 | #define LINELIM 4096
|
---|
18 | #define NPUSH 8 /* limit to input nesting */
|
---|
19 |
|
---|
20 | #define NOFILE 20 /* Number of open files */
|
---|
21 | #define NUFILE 10 /* Number of user-accessible files */
|
---|
22 | #define FDBASE 10 /* First file usable by Shell */
|
---|
23 |
|
---|
24 | /*
|
---|
25 | * values returned by wait
|
---|
26 | */
|
---|
27 | #define WAITSIG(s) ((s)&0177)
|
---|
28 | #define WAITVAL(s) (((s)>>8)&0377)
|
---|
29 | #define WAITCORE(s) (((s)&0200)!=0)
|
---|
30 |
|
---|
31 | /*
|
---|
32 | * library and system defintions
|
---|
33 | */
|
---|
34 | #ifdef __STDC__
|
---|
35 | typedef void xint; /* base type of jmp_buf, for not broken compilers */
|
---|
36 | #else
|
---|
37 | typedef char * xint; /* base type of jmp_buf, for broken compilers */
|
---|
38 | #endif
|
---|
39 |
|
---|
40 | /*
|
---|
41 | * shell components
|
---|
42 | */
|
---|
43 | /* #include "area.h" */
|
---|
44 | /* #include "word.h" */
|
---|
45 | /* #include "io.h" */
|
---|
46 | /* #include "var.h" */
|
---|
47 |
|
---|
48 | #define QUOTE 0200
|
---|
49 |
|
---|
50 | #define NOBLOCK ((struct op *)NULL)
|
---|
51 | #define NOWORD ((char *)NULL)
|
---|
52 | #define NOWORDS ((char **)NULL)
|
---|
53 | #define NOPIPE ((int *)NULL)
|
---|
54 |
|
---|
55 | /*
|
---|
56 | * Description of a command or an operation on commands.
|
---|
57 | * Might eventually use a union.
|
---|
58 | */
|
---|
59 | struct op {
|
---|
60 | int type; /* operation type, see below */
|
---|
61 | char **words; /* arguments to a command */
|
---|
62 | struct ioword **ioact; /* IO actions (eg, < > >>) */
|
---|
63 | struct op *left;
|
---|
64 | struct op *right;
|
---|
65 | char *str; /* identifier for case and for */
|
---|
66 | };
|
---|
67 |
|
---|
68 | #define TCOM 1 /* command */
|
---|
69 | #define TPAREN 2 /* (c-list) */
|
---|
70 | #define TPIPE 3 /* a | b */
|
---|
71 | #define TLIST 4 /* a [&;] b */
|
---|
72 | #define TOR 5 /* || */
|
---|
73 | #define TAND 6 /* && */
|
---|
74 | #define TFOR 7
|
---|
75 | #define TDO 8
|
---|
76 | #define TCASE 9
|
---|
77 | #define TIF 10
|
---|
78 | #define TWHILE 11
|
---|
79 | #define TUNTIL 12
|
---|
80 | #define TELIF 13
|
---|
81 | #define TPAT 14 /* pattern in case */
|
---|
82 | #define TBRACE 15 /* {c-list} */
|
---|
83 | #define TASYNC 16 /* c & */
|
---|
84 |
|
---|
85 | /*
|
---|
86 | * actions determining the environment of a process
|
---|
87 | */
|
---|
88 | #define BIT(i) (1<<(i))
|
---|
89 | #define FEXEC BIT(0) /* execute without forking */
|
---|
90 |
|
---|
91 | /*
|
---|
92 | * flags to control evaluation of words
|
---|
93 | */
|
---|
94 | #define DOSUB 1 /* interpret $, `, and quotes */
|
---|
95 | #define DOBLANK 2 /* perform blank interpretation */
|
---|
96 | #define DOGLOB 4 /* interpret [?* */
|
---|
97 | #define DOKEY 8 /* move words with `=' to 2nd arg. list */
|
---|
98 | #define DOTRIM 16 /* trim resulting string */
|
---|
99 |
|
---|
100 | #define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)
|
---|
101 |
|
---|
102 | Extern char **dolv;
|
---|
103 | Extern int dolc;
|
---|
104 | Extern int exstat;
|
---|
105 | Extern char gflg;
|
---|
106 | Extern int talking; /* interactive (talking-type wireless) */
|
---|
107 | Extern int execflg;
|
---|
108 | Extern int multiline; /* \n changed to ; */
|
---|
109 | Extern struct op *outtree; /* result from parser */
|
---|
110 |
|
---|
111 | Extern xint *failpt;
|
---|
112 | Extern xint *errpt;
|
---|
113 |
|
---|
114 | struct brkcon {
|
---|
115 | jmp_buf brkpt;
|
---|
116 | struct brkcon *nextlev;
|
---|
117 | } ;
|
---|
118 | Extern struct brkcon *brklist;
|
---|
119 | Extern int isbreak;
|
---|
120 |
|
---|
121 | /*
|
---|
122 | * redirection
|
---|
123 | */
|
---|
124 | struct ioword {
|
---|
125 | short io_unit; /* unit affected */
|
---|
126 | short io_flag; /* action (below) */
|
---|
127 | char *io_name; /* file name */
|
---|
128 | };
|
---|
129 | #define IOREAD 1 /* < */
|
---|
130 | #define IOHERE 2 /* << (here file) */
|
---|
131 | #define IOWRITE 4 /* > */
|
---|
132 | #define IOCAT 8 /* >> */
|
---|
133 | #define IOXHERE 16 /* ${}, ` in << */
|
---|
134 | #define IODUP 32 /* >&digit */
|
---|
135 | #define IOCLOSE 64 /* >&- */
|
---|
136 |
|
---|
137 | #define IODEFAULT (-1) /* token for default IO unit */
|
---|
138 |
|
---|
139 | Extern struct wdblock *wdlist;
|
---|
140 | Extern struct wdblock *iolist;
|
---|
141 |
|
---|
142 | /*
|
---|
143 | * parsing & execution environment
|
---|
144 | */
|
---|
145 | extern struct env {
|
---|
146 | char *linep;
|
---|
147 | struct io *iobase;
|
---|
148 | struct io *iop;
|
---|
149 | xint *errpt;
|
---|
150 | int iofd;
|
---|
151 | struct env *oenv;
|
---|
152 | } e;
|
---|
153 |
|
---|
154 | /*
|
---|
155 | * flags:
|
---|
156 | * -e: quit on error
|
---|
157 | * -k: look for name=value everywhere on command line
|
---|
158 | * -n: no execution
|
---|
159 | * -t: exit after reading and executing one command
|
---|
160 | * -v: echo as read
|
---|
161 | * -x: trace
|
---|
162 | * -u: unset variables net diagnostic
|
---|
163 | */
|
---|
164 | extern char *flag;
|
---|
165 |
|
---|
166 | extern char *null; /* null value for variable */
|
---|
167 | extern int intr; /* interrupt pending */
|
---|
168 |
|
---|
169 | Extern char *trap[_NSIG+1];
|
---|
170 | Extern char ourtrap[_NSIG+1];
|
---|
171 | Extern int trapset; /* trap pending */
|
---|
172 |
|
---|
173 | extern int heedint; /* heed interrupt signals */
|
---|
174 |
|
---|
175 | Extern int yynerrs; /* yacc */
|
---|
176 |
|
---|
177 | Extern char line[LINELIM];
|
---|
178 | extern char *elinep;
|
---|
179 |
|
---|
180 | /*
|
---|
181 | * other functions
|
---|
182 | */
|
---|
183 | #ifdef __STDC__
|
---|
184 | int (*inbuilt(char *s ))(void);
|
---|
185 | #else
|
---|
186 | int (*inbuilt())();
|
---|
187 | #endif
|
---|
188 | _PROTOTYPE(char *rexecve , (char *c , char **v , char **envp ));
|
---|
189 | _PROTOTYPE(char *space , (int n ));
|
---|
190 | _PROTOTYPE(char *strsave , (char *s , int a ));
|
---|
191 | _PROTOTYPE(char *evalstr , (char *cp , int f ));
|
---|
192 | _PROTOTYPE(char *putn , (int n ));
|
---|
193 | _PROTOTYPE(char *itoa , (unsigned u , int n ));
|
---|
194 | _PROTOTYPE(char *unquote , (char *as ));
|
---|
195 | _PROTOTYPE(struct var *lookup , (char *n ));
|
---|
196 | _PROTOTYPE(int rlookup , (char *n ));
|
---|
197 | _PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb ));
|
---|
198 | _PROTOTYPE(int subgetc , (int ec , int quoted ));
|
---|
199 | _PROTOTYPE(char **makenv , (void));
|
---|
200 | _PROTOTYPE(char **eval , (char **ap , int f ));
|
---|
201 | _PROTOTYPE(int setstatus , (int s ));
|
---|
202 | _PROTOTYPE(int waitfor , (int lastpid , int canintr ));
|
---|
203 |
|
---|
204 | _PROTOTYPE(void onintr , (int s )); /* SIGINT handler */
|
---|
205 |
|
---|
206 | _PROTOTYPE(int newenv , (int f ));
|
---|
207 | _PROTOTYPE(void quitenv , (void));
|
---|
208 | _PROTOTYPE(void err , (char *s ));
|
---|
209 | _PROTOTYPE(int anys , (char *s1 , char *s2 ));
|
---|
210 | _PROTOTYPE(int any , (int c , char *s ));
|
---|
211 | _PROTOTYPE(void next , (int f ));
|
---|
212 | _PROTOTYPE(void setdash , (void));
|
---|
213 | _PROTOTYPE(void onecommand , (void));
|
---|
214 | _PROTOTYPE(void runtrap , (int i ));
|
---|
215 | _PROTOTYPE(void xfree , (char *s ));
|
---|
216 | _PROTOTYPE(int letter , (int c ));
|
---|
217 | _PROTOTYPE(int digit , (int c ));
|
---|
218 | _PROTOTYPE(int letnum , (int c ));
|
---|
219 | _PROTOTYPE(int gmatch , (char *s , char *p ));
|
---|
220 |
|
---|
221 | /*
|
---|
222 | * error handling
|
---|
223 | */
|
---|
224 | _PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */
|
---|
225 | _PROTOTYPE(void fail , (void)); /* fail but return to process next command */
|
---|
226 | _PROTOTYPE(void warn , (char *s ));
|
---|
227 | _PROTOTYPE(void sig , (int i )); /* default signal handler */
|
---|
228 |
|
---|
229 | /* -------- var.h -------- */
|
---|
230 |
|
---|
231 | struct var {
|
---|
232 | char *value;
|
---|
233 | char *name;
|
---|
234 | struct var *next;
|
---|
235 | char status;
|
---|
236 | };
|
---|
237 | #define COPYV 1 /* flag to setval, suggesting copy */
|
---|
238 | #define RONLY 01 /* variable is read-only */
|
---|
239 | #define EXPORT 02 /* variable is to be exported */
|
---|
240 | #define GETCELL 04 /* name & value space was got with getcell */
|
---|
241 |
|
---|
242 | Extern struct var *vlist; /* dictionary */
|
---|
243 |
|
---|
244 | Extern struct var *homedir; /* home directory */
|
---|
245 | Extern struct var *prompt; /* main prompt */
|
---|
246 | Extern struct var *cprompt; /* continuation prompt */
|
---|
247 | Extern struct var *path; /* search path for commands */
|
---|
248 | Extern struct var *shell; /* shell to interpret command files */
|
---|
249 | Extern struct var *ifs; /* field separators */
|
---|
250 |
|
---|
251 | _PROTOTYPE(int yyparse , (void));
|
---|
252 | _PROTOTYPE(struct var *lookup , (char *n ));
|
---|
253 | _PROTOTYPE(void setval , (struct var *vp , char *val ));
|
---|
254 | _PROTOTYPE(void nameval , (struct var *vp , char *val , char *name ));
|
---|
255 | _PROTOTYPE(void export , (struct var *vp ));
|
---|
256 | _PROTOTYPE(void ronly , (struct var *vp ));
|
---|
257 | _PROTOTYPE(int isassign , (char *s ));
|
---|
258 | _PROTOTYPE(int checkname , (char *cp ));
|
---|
259 | _PROTOTYPE(int assign , (char *s , int cf ));
|
---|
260 | _PROTOTYPE(void putvlist , (int f , int out ));
|
---|
261 | _PROTOTYPE(int eqname , (char *n1 , char *n2 ));
|
---|
262 |
|
---|
263 | _PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act ));
|
---|
264 |
|
---|
265 | /* -------- io.h -------- */
|
---|
266 | /* io buffer */
|
---|
267 | struct iobuf {
|
---|
268 | unsigned id; /* buffer id */
|
---|
269 | char buf[512]; /* buffer */
|
---|
270 | char *bufp; /* pointer into buffer */
|
---|
271 | char *ebufp; /* pointer to end of buffer */
|
---|
272 | };
|
---|
273 |
|
---|
274 | /* possible arguments to an IO function */
|
---|
275 | struct ioarg {
|
---|
276 | char *aword;
|
---|
277 | char **awordlist;
|
---|
278 | int afile; /* file descriptor */
|
---|
279 | unsigned afid; /* buffer id */
|
---|
280 | long afpos; /* file position */
|
---|
281 | struct iobuf *afbuf; /* buffer for this file */
|
---|
282 | };
|
---|
283 | Extern struct ioarg ioargstack[NPUSH];
|
---|
284 | #define AFID_NOBUF (~0)
|
---|
285 | #define AFID_ID 0
|
---|
286 |
|
---|
287 | /* an input generator's state */
|
---|
288 | struct io {
|
---|
289 | int (*iofn)(_VOID);
|
---|
290 | struct ioarg *argp;
|
---|
291 | int peekc;
|
---|
292 | char prev; /* previous character read by readc() */
|
---|
293 | char nlcount; /* for `'s */
|
---|
294 | char xchar; /* for `'s */
|
---|
295 | char task; /* reason for pushed IO */
|
---|
296 | };
|
---|
297 | Extern struct io iostack[NPUSH];
|
---|
298 | #define XOTHER 0 /* none of the below */
|
---|
299 | #define XDOLL 1 /* expanding ${} */
|
---|
300 | #define XGRAVE 2 /* expanding `'s */
|
---|
301 | #define XIO 3 /* file IO */
|
---|
302 |
|
---|
303 | /* in substitution */
|
---|
304 | #define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
|
---|
305 |
|
---|
306 | /*
|
---|
307 | * input generators for IO structure
|
---|
308 | */
|
---|
309 | _PROTOTYPE(int nlchar , (struct ioarg *ap ));
|
---|
310 | _PROTOTYPE(int strchar , (struct ioarg *ap ));
|
---|
311 | _PROTOTYPE(int qstrchar , (struct ioarg *ap ));
|
---|
312 | _PROTOTYPE(int filechar , (struct ioarg *ap ));
|
---|
313 | _PROTOTYPE(int herechar , (struct ioarg *ap ));
|
---|
314 | _PROTOTYPE(int linechar , (struct ioarg *ap ));
|
---|
315 | _PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop ));
|
---|
316 | _PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop ));
|
---|
317 | _PROTOTYPE(int dolchar , (struct ioarg *ap ));
|
---|
318 | _PROTOTYPE(int wdchar , (struct ioarg *ap ));
|
---|
319 | _PROTOTYPE(void scraphere , (void));
|
---|
320 | _PROTOTYPE(void freehere , (int area ));
|
---|
321 | _PROTOTYPE(void gethere , (void));
|
---|
322 | _PROTOTYPE(void markhere , (char *s , struct ioword *iop ));
|
---|
323 | _PROTOTYPE(int herein , (char *hname , int xdoll ));
|
---|
324 | _PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID)));
|
---|
325 |
|
---|
326 | /*
|
---|
327 | * IO functions
|
---|
328 | */
|
---|
329 | _PROTOTYPE(int eofc , (void));
|
---|
330 | _PROTOTYPE(int getc , (int ec ));
|
---|
331 | _PROTOTYPE(int readc , (void));
|
---|
332 | _PROTOTYPE(void unget , (int c ));
|
---|
333 | _PROTOTYPE(void ioecho , (int c ));
|
---|
334 | _PROTOTYPE(void prs , (char *s ));
|
---|
335 | _PROTOTYPE(void putc , (int c ));
|
---|
336 | _PROTOTYPE(void prn , (unsigned u ));
|
---|
337 | _PROTOTYPE(void closef , (int i ));
|
---|
338 | _PROTOTYPE(void closeall , (void));
|
---|
339 |
|
---|
340 | /*
|
---|
341 | * IO control
|
---|
342 | */
|
---|
343 | _PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID)));
|
---|
344 | _PROTOTYPE(int remap , (int fd ));
|
---|
345 | _PROTOTYPE(int openpipe , (int *pv ));
|
---|
346 | _PROTOTYPE(void closepipe , (int *pv ));
|
---|
347 | _PROTOTYPE(struct io *setbase , (struct io *ip ));
|
---|
348 |
|
---|
349 | extern struct ioarg temparg; /* temporary for PUSHIO */
|
---|
350 | #define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
|
---|
351 | #define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
|
---|
352 |
|
---|
353 | /* -------- word.h -------- */
|
---|
354 | #ifndef WORD_H
|
---|
355 | #define WORD_H 1
|
---|
356 | struct wdblock {
|
---|
357 | short w_bsize;
|
---|
358 | short w_nword;
|
---|
359 | /* bounds are arbitrary */
|
---|
360 | char *w_words[1];
|
---|
361 | };
|
---|
362 |
|
---|
363 | _PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb ));
|
---|
364 | _PROTOTYPE(struct wdblock *newword , (int nw ));
|
---|
365 | _PROTOTYPE(char **getwords , (struct wdblock *wb ));
|
---|
366 | #endif
|
---|
367 |
|
---|
368 | /* -------- area.h -------- */
|
---|
369 |
|
---|
370 | /*
|
---|
371 | * storage allocation
|
---|
372 | */
|
---|
373 | _PROTOTYPE(char *getcell , (unsigned nbytes ));
|
---|
374 | _PROTOTYPE(void garbage , (void));
|
---|
375 | _PROTOTYPE(void setarea , (char *cp , int a ));
|
---|
376 | _PROTOTYPE(int getarea , (char *cp ));
|
---|
377 | _PROTOTYPE(void freearea , (int a ));
|
---|
378 | _PROTOTYPE(void freecell , (char *cp ));
|
---|
379 |
|
---|
380 | Extern int areanum; /* current allocation area */
|
---|
381 |
|
---|
382 | #define NEW(type) (type *)getcell(sizeof(type))
|
---|
383 | #define DELETE(obj) freecell((char *)obj)
|
---|