--- busybox-1.13.0/shell/ash.c Thu Oct 30 08:41:32 2008 +++ busybox-1.13.0-ash/shell/ash.c Fri Nov 28 04:39:17 2008 @@ -536,6 +536,7 @@ #define NHERE 24 #define NXHERE 25 #define NNOT 26 +#define N_NUMBER 27 union node; @@ -7546,43 +7547,46 @@ /* ============ eval.c */ -static int funcblocksize; /* size of structures in function */ -static int funcstringsize; /* size of strings in node */ -static void *funcblock; /* block to allocate function from */ -static char *funcstring; /* block to allocate strings from */ +static int funcblocksize; /* size of structures in function */ +static int funcstringsize; /* size of strings in node */ +static void *funcblock; /* block to allocate function from */ +static char *funcstring; /* block to allocate strings from */ /* flags in argument to evaltree */ -#define EV_EXIT 01 /* exit after evaluating tree */ -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ +#define EV_EXIT 01 /* exit after evaluating tree */ +#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ #define EV_BACKCMD 04 /* command executing within back quotes */ -static const short nodesize[26] = { - SHELL_ALIGN(sizeof(struct ncmd)), - SHELL_ALIGN(sizeof(struct npipe)), - SHELL_ALIGN(sizeof(struct nredir)), - SHELL_ALIGN(sizeof(struct nredir)), - SHELL_ALIGN(sizeof(struct nredir)), - SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nif)), - SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nfor)), - SHELL_ALIGN(sizeof(struct ncase)), - SHELL_ALIGN(sizeof(struct nclist)), - SHELL_ALIGN(sizeof(struct narg)), - SHELL_ALIGN(sizeof(struct narg)), - SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct ndup)), - SHELL_ALIGN(sizeof(struct ndup)), - SHELL_ALIGN(sizeof(struct nhere)), - SHELL_ALIGN(sizeof(struct nhere)), - SHELL_ALIGN(sizeof(struct nnot)), +static const short nodesize[N_NUMBER] = { + [NCMD ] = SHELL_ALIGN(sizeof(struct ncmd)), + [NPIPE ] = SHELL_ALIGN(sizeof(struct npipe)), + [NREDIR ] = SHELL_ALIGN(sizeof(struct nredir)), + [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)), + [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)), + [NAND ] = SHELL_ALIGN(sizeof(struct nbinary)), + [NOR ] = SHELL_ALIGN(sizeof(struct nbinary)), + [NSEMI ] = SHELL_ALIGN(sizeof(struct nbinary)), + [NIF ] = SHELL_ALIGN(sizeof(struct nif)), + [NWHILE ] = SHELL_ALIGN(sizeof(struct nbinary)), + [NUNTIL ] = SHELL_ALIGN(sizeof(struct nbinary)), + [NFOR ] = SHELL_ALIGN(sizeof(struct nfor)), + [NCASE ] = SHELL_ALIGN(sizeof(struct ncase)), + [NCLIST ] = SHELL_ALIGN(sizeof(struct nclist)), + [NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)), + [NARG ] = SHELL_ALIGN(sizeof(struct narg)), + [NTO ] = SHELL_ALIGN(sizeof(struct nfile)), +#if ENABLE_ASH_BASH_COMPAT + [NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)), +#endif + [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)), + [NFROM ] = SHELL_ALIGN(sizeof(struct nfile)), + [NFROMTO ] = SHELL_ALIGN(sizeof(struct nfile)), + [NAPPEND ] = SHELL_ALIGN(sizeof(struct nfile)), + [NTOFD ] = SHELL_ALIGN(sizeof(struct ndup)), + [NFROMFD ] = SHELL_ALIGN(sizeof(struct ndup)), + [NHERE ] = SHELL_ALIGN(sizeof(struct nhere)), + [NXHERE ] = SHELL_ALIGN(sizeof(struct nhere)), + [NNOT ] = SHELL_ALIGN(sizeof(struct nnot)), }; static void calcsize(union node *n); @@ -9065,8 +9069,6 @@ * This implements the input routines used by the parser. */ -#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ - enum { INPUT_PUSH_FILE = 1, INPUT_NOFILE_OK = 2, @@ -9107,7 +9109,6 @@ #endif parsenextc = sp->prevstring; parsenleft = sp->prevnleft; -/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ g_parsefile->strpush = sp->prev; if (sp != &(g_parsefile->basestrpush)) free(sp); @@ -9123,7 +9124,7 @@ #if ENABLE_FEATURE_EDITING retry: - if (!iflag || g_parsefile->fd) + if (!iflag || g_parsefile->fd != STDIN_FILENO) nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1); else { #if ENABLE_FEATURE_TAB_COMPLETION @@ -9171,55 +9172,76 @@ * Refill the input buffer and return the next input character: * * 1) If a string was pushed back on the input, pop it; - * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading + * 2) If an EOF was pushed back (parsenleft < -BIGNUM) or we are reading * from a string so we can't refill the buffer, return EOF. * 3) If the is more stuff in this buffer, use it else call read to fill it. * 4) Process input up to the next newline, deleting nul characters. */ +//#define pgetc_debug(...) bb_error_msg(__VA_ARGS__) +#define pgetc_debug(...) ((void)0) static int preadbuffer(void) { char *q; int more; - char savec; while (g_parsefile->strpush) { #if ENABLE_ASH_ALIAS - if (parsenleft == -1 && g_parsefile->strpush->ap && - parsenextc[-1] != ' ' && parsenextc[-1] != '\t') { + if (parsenleft == -1 && g_parsefile->strpush->ap + && parsenextc[-1] != ' ' && parsenextc[-1] != '\t' + ) { + pgetc_debug("preadbuffer PEOA"); return PEOA; } #endif popstring(); + /* try "pgetc" now: */ + pgetc_debug("internal pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc); if (--parsenleft >= 0) return signed_char2int(*parsenextc++); } - if (parsenleft == EOF_NLEFT || g_parsefile->buf == NULL) + /* on both branches above parsenleft < 0. + * "pgetc" needs refilling. + */ + + /* -90 is -BIGNUM. Below we use -99 to mark "EOF on read", + * pungetc() may decrement it a few times. -90 is enough. + */ + if (parsenleft < -90 || g_parsefile->buf == NULL) { + pgetc_debug("preadbuffer PEOF1"); + /* even in failure keep them in lock step, + * for correct pungetc. */ + parsenextc++; return PEOF; - flush_stdout_stderr(); + } more = parselleft; if (more <= 0) { + flush_stdout_stderr(); again: more = preadfd(); if (more <= 0) { - parselleft = parsenleft = EOF_NLEFT; + parselleft = parsenleft = -99; + pgetc_debug("preadbuffer PEOF2"); + parsenextc++; return PEOF; } } + /* Find out where's the end of line. + * Set parsenleft/parselleft acordingly. + * NUL chars are deleted. + */ q = parsenextc; - - /* delete nul characters */ for (;;) { - int c; + char c; more--; - c = *q; - if (!c) + c = *q; + if (c == '\0') { memmove(q, q + 1, more); - else { + } else { q++; if (c == '\n') { parsenleft = q - parsenextc - 1; @@ -9236,22 +9258,23 @@ } parselleft = more; - savec = *q; - *q = '\0'; - if (vflag) { + char save = *q; + *q = '\0'; out2str(parsenextc); + *q = save; } - *q = savec; - + pgetc_debug("preadbuffer at %d:%p'%s'", parsenleft, parsenextc, parsenextc); return signed_char2int(*parsenextc++); } #define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer()) + static int pgetc(void) { + pgetc_debug("pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc); return pgetc_as_macro(); } @@ -9312,6 +9335,7 @@ { parsenleft++; parsenextc--; + pgetc_debug("pushed back to %d:%p'%s'", parsenleft, parsenextc, parsenextc); } /* @@ -9325,16 +9349,17 @@ pushstring(char *s, struct alias *ap) { struct strpush *sp; - size_t len; + int len; len = strlen(s); INT_OFF; if (g_parsefile->strpush) { - sp = ckzalloc(sizeof(struct strpush)); + sp = ckzalloc(sizeof(*sp)); sp->prev = g_parsefile->strpush; - g_parsefile->strpush = sp; - } else - sp = g_parsefile->strpush = &(g_parsefile->basestrpush); + } else { + sp = &(g_parsefile->basestrpush); + } + g_parsefile->strpush = sp; sp->prevstring = parsenextc; sp->prevnleft = parsenleft; #if ENABLE_ASH_ALIAS @@ -9424,7 +9449,7 @@ close_on_exec_on(fd); if (push) { pushfile(); - g_parsefile->buf = 0; + g_parsefile->buf = NULL; } g_parsefile->fd = fd; if (g_parsefile->buf == NULL)