|
|
1.1 ! root 1: /* ! 2: * sh/sh.h ! 3: * Bourne shell. ! 4: */ ! 5: ! 6: #include <stdio.h> ! 7: #include <setjmp.h> ! 8: #include <string.h> ! 9: ! 10: #define STRSIZE 2000 /* Maximum length of single token */ ! 11: #define IALSIZE 8 /* Initial argument list size */ ! 12: #define DSTACKN 30 /* Directory stack depth */ ! 13: #define NOTREACHED return ! 14: ! 15: ! 16: /* ! 17: * Masks for looking up lextab. ! 18: */ ! 19: ! 20: #define MNQUO 0x01 /* Special in argument */ ! 21: #define MDQUO 0x02 /* Special in double quotes */ ! 22: #define MHERE 0x04 /* Special in here document */ ! 23: #define MRVAR (MBVAR | MDIGI) /* Valid in regular variable name */ ! 24: /* 0x08 was MSVAR, now is spare */ ! 25: #define MDIGI 0x10 /* Is an ascii digit */ ! 26: #define MBVAR 0x20 /* Valid 1st char in regular var name */ ! 27: #define MNAME 0x40 /* Does not start a name */ ! 28: #define MGLOB 0x80 /* Must call glob */ ! 29: ! 30: #define SPECIAL_VAR_CHARS "!#$*-0123456789?@" ! 31: ! 32: ! 33: /* ! 34: * Determine if a character is a member of the given class. ! 35: * (This depends of the fact that EOF == -1). ! 36: */ ! 37: ! 38: #define class(c, m) ((unsigned) (c - EOF) <= (unsigned) (0x7F - EOF) && \ ! 39: (lextab [c - EOF] & m) != 0) ! 40: ! 41: /* ! 42: * Types of nodes. ! 43: */ ! 44: ! 45: #define NNULL 0 /* Null */ ! 46: #define NFOR 1 /* For */ ! 47: #define NCASE 2 /* Case */ ! 48: #define NWHILE 3 /* While */ ! 49: #define NUNTIL 4 /* Until */ ! 50: #define NIF 5 /* If */ ! 51: #define NELSE 6 /* Else */ ! 52: #define NCOMS 7 /* Command sequence */ ! 53: #define NLIST 8 /* Command list */ ! 54: #define NBACK 9 /* Background process */ ! 55: #define NPIPE 10 /* Pipe */ ! 56: #define NPARN 11 /* New shell */ ! 57: #define NBRAC 12 /* Command group */ ! 58: #define NANDF 13 /* Logical and operator */ ! 59: #define NORF 14 /* Logical or operator */ ! 60: #define NARGS 15 /* Argument string */ ! 61: #define NIORS 16 /* Redirection of io */ ! 62: #define NASSG 17 /* Assignment keyword */ ! 63: #define NFOR2 18 /* Second part for, in list scan */ ! 64: #define NCASE2 19 /* Second part case, command */ ! 65: #define NCASE3 20 /* Third part case, pattern */ ! 66: #define NCTRL 21 /* Control statement in list */ ! 67: #define NRPIPE 22 /* Named pipe for read */ ! 68: #define NWPIPE 23 /* Named pipe for write */ ! 69: #define NFUNC 24 /* Shell function */ ! 70: #define NRET 25 /* Return */ ! 71: ! 72: ! 73: /* ! 74: * Node. ! 75: */ ! 76: ! 77: typedef struct node { ! 78: int n_type; /* Type of node */ ! 79: struct node *n_next; /* Pointer to next */ ! 80: union { ! 81: struct node *nu_auxp; /* Auxiliary pointer */ ! 82: char *nu_strp; /* Pointer to string */ ! 83: } n_u; ! 84: } NODE; ! 85: #define n_auxp n_u.nu_auxp ! 86: #define n_strp n_u.nu_strp ! 87: ! 88: ! 89: /* ! 90: * Flags in variables. ! 91: */ ! 92: ! 93: #define VEXP 001 /* Variable is exported */ ! 94: #define VRDO 002 /* Read only */ ! 95: #define VSET 004 /* Variable is used by shell */ ! 96: ! 97: ! 98: /* ! 99: * Enviroment list and variable structure. ! 100: */ ! 101: ! 102: typedef struct var { ! 103: int v_flag; /* Flags */ ! 104: struct var *v_next; /* Pointer to next entry */ ! 105: char *v_strp; /* Pointer to string */ ! 106: } VAR; ! 107: ! 108: ! 109: /* ! 110: * Buffer structure. ! 111: */ ! 112: ! 113: typedef struct buf { ! 114: struct buf *b_next; /* Pointer to next */ ! 115: int b_size; /* Size of buffer */ ! 116: } BUF; ! 117: ! 118: ! 119: /* ! 120: * NB: Here-document processing in shell functions places extra demands on ! 121: * the management of temporary files. When a shell function is interned, any ! 122: * here documents created within the function are turned into temporary ! 123: * files which must persist for the life of the function (ie, until the ! 124: * shell exits or the function is removed via "unset -f"). ! 125: * ! 126: * The following data structure is intended to allow the temporary-file ! 127: * context to be managed in the manner required. A pointer to a list of these ! 128: * structures is stored in the function definition, taken from the global ! 129: * list of temporary files when a function is defined. ! 130: * ! 131: * Related functions: ! 132: * def_sh_fn (nodep) ! 133: * Captures the current temporary-file context and attaches it ! 134: * to the shell function being defined. ! 135: * remember_temp (filename) ! 136: * Adds a filename to the current global list of temporary ! 137: * files (copies filename to private buffer). ! 138: * capture_temp () ! 139: * Detaches the global list of temporary files and returns ! 140: * the list to the caller. ! 141: * unlink_temp (templist) ! 142: * Walks over the list of temporary files, unlinking the files ! 143: * and deallocating the list nodes. ! 144: * forget_temp (templist) ! 145: * Deallocates the memory for the list of temporary files. ! 146: */ ! 147: ! 148: typedef struct temp_file TEMP_FILE; ! 149: ! 150: struct temp_file { ! 151: TEMP_FILE * tf_next; ! 152: char * tf_name; ! 153: }; ! 154: ! 155: ! 156: /* ! 157: * Per executing command data structure. ! 158: * Used for break/continue. ! 159: */ ! 160: ! 161: typedef struct con { ! 162: struct con *c_next; /* Pointer to next */ ! 163: NODE *c_node; /* Node which created this control */ ! 164: BUF **c_bpp; /* Current free buffer */ ! 165: jmp_buf c_envl; /* Enviroment list */ ! 166: TEMP_FILE * c_temp; /* temporary files */ ! 167: } CON; ! 168: ! 169: #define DESTROY_CON(cp) (freebuf ((cp)->c_bpp), \ ! 170: (cp)->c_temp != NULL ? unlink_temp ((cp)->c_temp) : \ ! 171: (void) 0) ! 172: ! 173: /* ! 174: * Shell functions. ! 175: */ ! 176: ! 177: typedef struct shfunc { ! 178: struct shfunc *fn_link; ! 179: int fn_hash; ! 180: char *fn_name; ! 181: NODE *fn_body; ! 182: TEMP_FILE * fn_temp; ! 183: } SHFUNC; ! 184: ! 185: ! 186: /* ! 187: * Session types. ! 188: */ ! 189: ! 190: #define SINIT 0 /* Initial session */ ! 191: #define SARGS 1 /* String */ ! 192: #define SARGV 2 /* Vector of strings */ ! 193: #define SFILE 3 /* File name */ ! 194: #define SSTR 4 /* Open stream */ ! 195: ! 196: ! 197: /* ! 198: * Per session information structure. ! 199: */ ! 200: ! 201: typedef struct ses { ! 202: struct ses *s_next; ! 203: int s_type; ! 204: int s_flag; ! 205: NODE *s_node; ! 206: CON *s_con; ! 207: BUF **s_bpp; ! 208: jmp_buf s_envl; ! 209: char *s_strp; ! 210: char **s_argv; ! 211: FILE *s_ifp; ! 212: } SES; ! 213: ! 214: ! 215: /* ! 216: * Session long jump codes ! 217: */ ! 218: ! 219: #define RSET 0 /* Initial setjmp call */ ! 220: #define REOF 1 /* parse matched start */ ! 221: #define RCMD 2 /* parse matched command line */ ! 222: #define RERR 3 /* parse matched error */ ! 223: #define RINT 4 /* Interrupt recovery */ ! 224: #define RNOSBRK 5 /* no more memory from alloc */ ! 225: #define RSYSER 6 /* system returned -1 */ ! 226: #define RUABORT 7 /* user requested error abort */ ! 227: #define RUEXITS 8 /* user requested exit command */ ! 228: #define RBRKCON 9 /* break or continue beyond program */ ! 229: #define RNOWAY 10 /* Shell assertion failed */ ! 230: ! 231: ! 232: /* ! 233: * Interrupt recovery and set contexts. ! 234: * Used to determine recovery action and default signals. ! 235: */ ! 236: ! 237: #define IRDY 0 /* In session */ ! 238: #define ILEX 1 /* Parse in progress */ ! 239: #define ICMD 2 /* Prior to next command execution */ ! 240: #define IEVAL 3 /* Command evaluation in progress */ ! 241: #define IBACK 4 /* Background process */ ! 242: #define IFORK 5 /* Child after fork */ ! 243: #define IPROF 6 /* Reading /etc/profile for login */ ! 244: ! 245: ! 246: /* ! 247: * Evaluation contexts. ! 248: */ ! 249: ! 250: #define EWORD 0 /* Evaluate $N, `cmd`, strip quotes */ ! 251: #define EHERE 1 /* Evaluate $N, `cmd`, ignore quotes */ ! 252: #define EARGS 2 /* Evaluete $N, `cmd`, strip quotes, *?[, blanks */ ! 253: #define EPATT 3 /* Evaluate for pattern match */ ! 254: ! 255: ! 256: /* ! 257: * NB : The shell is required to permit redirections of built-ins and special ! 258: * built-in operations in such a way that they are not run in subshells (since ! 259: * they have to affect the top-level environment). To permit this, the ! 260: * redirection code makes duplicates of file descriptors it overwrites and ! 261: * records all the information necessary to reverse the effect of the ! 262: * redirections on the global environment. This structure holds the "undo" ! 263: * information. Note that "ru_newfd" may be set to -1 if the fd that was ! 264: * redirected did not originally refer to an open file. ! 265: * ! 266: * Related functions: ! 267: * redirect (iovp, undo) ! 268: * The "undo" argument is an optional pointer to the head of a ! 269: * list of REDIR_UNDO entries. ! 270: * redirundo (undo) ! 271: * Processes a list of REDIR_UNDO entries. ! 272: */ ! 273: ! 274: typedef struct redir_undo REDIR_UNDO; ! 275: ! 276: struct redir_undo { ! 277: REDIR_UNDO * ru_next; /* link to next undo item */ ! 278: int ru_oldfd; /* fd changed by redirection */ ! 279: int ru_newfd; /* duplicate of original fd */ ! 280: }; ! 281: ! 282: ! 283: /* ! 284: * Flags for controlling collect () in lex.c ! 285: */ ! 286: ! 287: enum { ! 288: CONSUME_BACKSLASH, /* ! 289: * Allow back-slash quoting of anything and ! 290: * consume the backslashes. ! 291: */ ! 292: BACKSLASH_END, /* ! 293: * Recognise backslash-quoting of the end ! 294: * character, but retain the backslash. ! 295: */ ! 296: NO_BACKSLASH, /* backslashes are ordinary */ ! 297: NO_ERRORS /* backslashes are ordinary, silent errors */ ! 298: }; ! 299: ! 300: ! 301: /* ! 302: * Global variables. ! 303: * Run time and set time flags. ! 304: */ ! 305: ! 306: extern char shflags[]; /* Flag array */ ! 307: extern char shfnams[]; /* Flag name array */ ! 308: ! 309: #define eflag shflags[0] /* Exit on non-zero status */ ! 310: #define kflag shflags[1] /* All assignments into environ */ ! 311: #define nflag shflags[2] /* Do not execute commands */ ! 312: #define pflag shflags[3] /* Unknown */ ! 313: #define tflag shflags[4] /* Exit after read/exec one command */ ! 314: #define uflag shflags[5] /* Unset variables are errors */ ! 315: #define vflag shflags[6] /* Print input as read */ ! 316: #define xflag shflags[7] /* Print commands as executed */ ! 317: ! 318: #define cflag shflags[8] /* Execute argument as command */ ! 319: #define iflag shflags[9] /* Be interactive shell */ ! 320: #define rflag shflags[10] /* Restricted shell */ ! 321: #define sflag shflags[11] /* input<&0, output>&2 */ ! 322: ! 323: #define lgnflag shflags[12] /* Login shell */ ! 324: #define no1flag shflags[13] /* Invoked shell */ ! 325: #define bckflag shflags[14] /* Background process */ ! 326: #define nllflag shflags[15] /* Forked shell */ ! 327: #define cmdflag shflags[16] /* Command file processor */ ! 328: ! 329: ! 330: /* Shell status housekeeping */ ! 331: ! 332: extern jmp_buf restart; /* Restart execution context */ ! 333: extern SHFUNC *sh_fnp; /* User-defined shell function list */ ! 334: extern int in_sh_fn; /* Executing shell function */ ! 335: extern int ret_done; /* "return" executed */ ! 336: extern int sargc; /* Argument count to shell */ ! 337: extern char *sarg0; /* Name shell called with */ ! 338: extern char **sargv; /* Argument vector to shell */ ! 339: extern char **senvp; /* Environment vector to shell */ ! 340: extern char **sargp; /* Current argument to shell */ ! 341: extern char *scmdp; /* Path/filename of command file */ ! 342: extern int nargc; /* New argument count, for command */ ! 343: extern char **nargv; /* New argument vector, for command */ ! 344: extern char **nenvp; /* New environment, for command */ ! 345: extern char **niovp; /* Io redirection, for command */ ! 346: extern NODE *nctlp; /* Control node, for command */ ! 347: extern SES *sesp; /* Current session structure */ ! 348: extern int yyline; /* Yacc command line counter */ ! 349: extern int shpid; /* Shell's process id */ ! 350: extern int slret; /* Exit status of last command */ ! 351: extern int sback; /* Pid of last background command */ ! 352: extern int spipe; /* Pid of last pipe process */ ! 353: extern int ufmask; /* File creation mask */ ! 354: ! 355: /* Other internal flags. */ ! 356: ! 357: extern int comflag; /* Command line is complete?? */ ! 358: extern int errflag; /* Set by call to printe */ ! 359: extern int keyflag; /* Look for keyword in next word */ ! 360: extern int noeflag; /* Turn off errors */ ! 361: extern int prpflag; /* Do prompt before next read */ ! 362: extern int readflag; /* Doing read command? */ ! 363: ! 364: /* Parameters used by shell. */ ! 365: ! 366: extern char *vhome; /* Home directory */ ! 367: extern char *vpath; /* Search pathname */ ! 368: extern char *vmail; /* Mail file */ ! 369: extern char *vps1; /* Prompt string 1 */ ! 370: extern char *vps2; /* Prompt string 2 */ ! 371: extern char *vifs; /* Internal field seperators */ ! 372: extern char *vshell; /* Shell to use */ ! 373: ! 374: /* Shell data */ ! 375: ! 376: extern char strt[STRSIZE]; /* String buffer */ ! 377: extern char *strp; /* Pointer in string buffer */ ! 378: extern VAR *varp; /* Pointer to shell variables */ ! 379: extern char *dstack[DSTACKN]; /* Directory stack */ ! 380: extern int dstkp; /* Directory stack pointer */ ! 381: ! 382: /* Tables */ ! 383: ! 384: extern unsigned char lextab[]; /* Character type table */ ! 385: ! 386: /* Data external to shell */ ! 387: ! 388: extern int errno; /* System call error number */ ! 389: extern char *signame[]; /* Wait status message table */ ! 390: ! 391: ! 392: /* ! 393: * Functions. ! 394: */ ! 395: ! 396: extern char *shtmp(); /* in main.c */ ! 397: extern char *salloc(); /* in alloc.c */ ! 398: extern char *balloc(); /* in alloc.c */ ! 399: extern char *duplstr(); /* in alloc.c */ ! 400: extern char **makargl(); /* in alloc.c */ ! 401: extern char **addargl(); /* in alloc.c */ ! 402: extern BUF **savebuf(); /* in alloc.c */ ! 403: extern char **vdupl(); /* in alloc.c */ ! 404: extern char *gany(); /* in glob.c */ ! 405: extern void sigintr(); /* in trap.c */ ! 406: extern VAR *findvar(); /* in var.c */ ! 407: extern VAR *setsvar(); /* in var.c */ ! 408: extern VAR *flagvar(); /* in var.c */ ! 409: extern VAR *assnvar(); /* in var.c */ ! 410: extern char *convvar(); /* in var.c */ ! 411: extern char **envlvar(); /* in var.c */ ! 412: extern char *_getwd(); /* in /lib/libc.a */ ! 413: ! 414: ! 415: /* NB: new stuff for shell functions */ ! 416: ! 417: extern TEMP_FILE * capture_temp (); /* main.c */ ! 418: extern void unlink_temp (); /* main.c */ ! 419: extern void cleanup_shell_fns (); /* exec3.c */ ! 420: ! 421: #ifdef ALLOC_DEBUG ! 422: struct alloc_debug { ! 423: char * name; ! 424: int count; ! 425: int maxcount; ! 426: }; ! 427: # define ALLOC_COUNT(x) struct alloc_debug x##debug = { #x }; ! 428: # define ALLOC_ALLOC(x) alloc_alloc (& x##debug); ! 429: # define ALLOC_FREE(x) x##debug.count --; ! 430: # ! 431: #else ! 432: # define ALLOC_COUNT(x) ! 433: # define ALLOC_ALLOC(x) ! 434: # define ALLOC_FREE(x) ! 435: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.