[9] | 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)
|
---|