aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-11-29 06:49:36 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-11-29 06:49:36 +0000
commitab310e1b1c2f85235e61c471802b53314da919f0 (patch)
tree415cf40159a0c2b6009a27df18b0cc45bea2e956 /shell
parent1cd1012a9063656a6b5b75dac8d400abd60cd643 (diff)
downloadbusybox-w32-ab310e1b1c2f85235e61c471802b53314da919f0.tar.gz
busybox-w32-ab310e1b1c2f85235e61c471802b53314da919f0.tar.bz2
busybox-w32-ab310e1b1c2f85235e61c471802b53314da919f0.zip
apply post-1.13.0 patches
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c147
1 files changed, 86 insertions, 61 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 92aa5ecc0..d6fd38849 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -536,6 +536,7 @@ static const char dolatstr[] ALIGN1 = {
536#define NHERE 24 536#define NHERE 24
537#define NXHERE 25 537#define NXHERE 25
538#define NNOT 26 538#define NNOT 26
539#define N_NUMBER 27
539 540
540union node; 541union node;
541 542
@@ -7546,43 +7547,46 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
7546 7547
7547/* ============ eval.c */ 7548/* ============ eval.c */
7548 7549
7549static int funcblocksize; /* size of structures in function */ 7550static int funcblocksize; /* size of structures in function */
7550static int funcstringsize; /* size of strings in node */ 7551static int funcstringsize; /* size of strings in node */
7551static void *funcblock; /* block to allocate function from */ 7552static void *funcblock; /* block to allocate function from */
7552static char *funcstring; /* block to allocate strings from */ 7553static char *funcstring; /* block to allocate strings from */
7553 7554
7554/* flags in argument to evaltree */ 7555/* flags in argument to evaltree */
7555#define EV_EXIT 01 /* exit after evaluating tree */ 7556#define EV_EXIT 01 /* exit after evaluating tree */
7556#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ 7557#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
7557#define EV_BACKCMD 04 /* command executing within back quotes */ 7558#define EV_BACKCMD 04 /* command executing within back quotes */
7558 7559
7559static const short nodesize[26] = { 7560static const short nodesize[N_NUMBER] = {
7560 SHELL_ALIGN(sizeof(struct ncmd)), 7561 [NCMD ] = SHELL_ALIGN(sizeof(struct ncmd)),
7561 SHELL_ALIGN(sizeof(struct npipe)), 7562 [NPIPE ] = SHELL_ALIGN(sizeof(struct npipe)),
7562 SHELL_ALIGN(sizeof(struct nredir)), 7563 [NREDIR ] = SHELL_ALIGN(sizeof(struct nredir)),
7563 SHELL_ALIGN(sizeof(struct nredir)), 7564 [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
7564 SHELL_ALIGN(sizeof(struct nredir)), 7565 [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
7565 SHELL_ALIGN(sizeof(struct nbinary)), 7566 [NAND ] = SHELL_ALIGN(sizeof(struct nbinary)),
7566 SHELL_ALIGN(sizeof(struct nbinary)), 7567 [NOR ] = SHELL_ALIGN(sizeof(struct nbinary)),
7567 SHELL_ALIGN(sizeof(struct nbinary)), 7568 [NSEMI ] = SHELL_ALIGN(sizeof(struct nbinary)),
7568 SHELL_ALIGN(sizeof(struct nif)), 7569 [NIF ] = SHELL_ALIGN(sizeof(struct nif)),
7569 SHELL_ALIGN(sizeof(struct nbinary)), 7570 [NWHILE ] = SHELL_ALIGN(sizeof(struct nbinary)),
7570 SHELL_ALIGN(sizeof(struct nbinary)), 7571 [NUNTIL ] = SHELL_ALIGN(sizeof(struct nbinary)),
7571 SHELL_ALIGN(sizeof(struct nfor)), 7572 [NFOR ] = SHELL_ALIGN(sizeof(struct nfor)),
7572 SHELL_ALIGN(sizeof(struct ncase)), 7573 [NCASE ] = SHELL_ALIGN(sizeof(struct ncase)),
7573 SHELL_ALIGN(sizeof(struct nclist)), 7574 [NCLIST ] = SHELL_ALIGN(sizeof(struct nclist)),
7574 SHELL_ALIGN(sizeof(struct narg)), 7575 [NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)),
7575 SHELL_ALIGN(sizeof(struct narg)), 7576 [NARG ] = SHELL_ALIGN(sizeof(struct narg)),
7576 SHELL_ALIGN(sizeof(struct nfile)), 7577 [NTO ] = SHELL_ALIGN(sizeof(struct nfile)),
7577 SHELL_ALIGN(sizeof(struct nfile)), 7578#if ENABLE_ASH_BASH_COMPAT
7578 SHELL_ALIGN(sizeof(struct nfile)), 7579 [NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)),
7579 SHELL_ALIGN(sizeof(struct nfile)), 7580#endif
7580 SHELL_ALIGN(sizeof(struct nfile)), 7581 [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
7581 SHELL_ALIGN(sizeof(struct ndup)), 7582 [NFROM ] = SHELL_ALIGN(sizeof(struct nfile)),
7582 SHELL_ALIGN(sizeof(struct ndup)), 7583 [NFROMTO ] = SHELL_ALIGN(sizeof(struct nfile)),
7583 SHELL_ALIGN(sizeof(struct nhere)), 7584 [NAPPEND ] = SHELL_ALIGN(sizeof(struct nfile)),
7584 SHELL_ALIGN(sizeof(struct nhere)), 7585 [NTOFD ] = SHELL_ALIGN(sizeof(struct ndup)),
7585 SHELL_ALIGN(sizeof(struct nnot)), 7586 [NFROMFD ] = SHELL_ALIGN(sizeof(struct ndup)),
7587 [NHERE ] = SHELL_ALIGN(sizeof(struct nhere)),
7588 [NXHERE ] = SHELL_ALIGN(sizeof(struct nhere)),
7589 [NNOT ] = SHELL_ALIGN(sizeof(struct nnot)),
7586}; 7590};
7587 7591
7588static void calcsize(union node *n); 7592static void calcsize(union node *n);
@@ -9065,8 +9069,6 @@ breakcmd(int argc UNUSED_PARAM, char **argv)
9065 * This implements the input routines used by the parser. 9069 * This implements the input routines used by the parser.
9066 */ 9070 */
9067 9071
9068#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
9069
9070enum { 9072enum {
9071 INPUT_PUSH_FILE = 1, 9073 INPUT_PUSH_FILE = 1,
9072 INPUT_NOFILE_OK = 2, 9074 INPUT_NOFILE_OK = 2,
@@ -9107,7 +9109,6 @@ popstring(void)
9107#endif 9109#endif
9108 parsenextc = sp->prevstring; 9110 parsenextc = sp->prevstring;
9109 parsenleft = sp->prevnleft; 9111 parsenleft = sp->prevnleft;
9110/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
9111 g_parsefile->strpush = sp->prev; 9112 g_parsefile->strpush = sp->prev;
9112 if (sp != &(g_parsefile->basestrpush)) 9113 if (sp != &(g_parsefile->basestrpush))
9113 free(sp); 9114 free(sp);
@@ -9123,7 +9124,7 @@ preadfd(void)
9123 9124
9124#if ENABLE_FEATURE_EDITING 9125#if ENABLE_FEATURE_EDITING
9125 retry: 9126 retry:
9126 if (!iflag || g_parsefile->fd) 9127 if (!iflag || g_parsefile->fd != STDIN_FILENO)
9127 nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1); 9128 nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1);
9128 else { 9129 else {
9129#if ENABLE_FEATURE_TAB_COMPLETION 9130#if ENABLE_FEATURE_TAB_COMPLETION
@@ -9171,55 +9172,76 @@ preadfd(void)
9171 * Refill the input buffer and return the next input character: 9172 * Refill the input buffer and return the next input character:
9172 * 9173 *
9173 * 1) If a string was pushed back on the input, pop it; 9174 * 1) If a string was pushed back on the input, pop it;
9174 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading 9175 * 2) If an EOF was pushed back (parsenleft < -BIGNUM) or we are reading
9175 * from a string so we can't refill the buffer, return EOF. 9176 * from a string so we can't refill the buffer, return EOF.
9176 * 3) If the is more stuff in this buffer, use it else call read to fill it. 9177 * 3) If the is more stuff in this buffer, use it else call read to fill it.
9177 * 4) Process input up to the next newline, deleting nul characters. 9178 * 4) Process input up to the next newline, deleting nul characters.
9178 */ 9179 */
9180//#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
9181#define pgetc_debug(...) ((void)0)
9179static int 9182static int
9180preadbuffer(void) 9183preadbuffer(void)
9181{ 9184{
9182 char *q; 9185 char *q;
9183 int more; 9186 int more;
9184 char savec;
9185 9187
9186 while (g_parsefile->strpush) { 9188 while (g_parsefile->strpush) {
9187#if ENABLE_ASH_ALIAS 9189#if ENABLE_ASH_ALIAS
9188 if (parsenleft == -1 && g_parsefile->strpush->ap && 9190 if (parsenleft == -1 && g_parsefile->strpush->ap
9189 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') { 9191 && parsenextc[-1] != ' ' && parsenextc[-1] != '\t'
9192 ) {
9193 pgetc_debug("preadbuffer PEOA");
9190 return PEOA; 9194 return PEOA;
9191 } 9195 }
9192#endif 9196#endif
9193 popstring(); 9197 popstring();
9198 /* try "pgetc" now: */
9199 pgetc_debug("internal pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
9194 if (--parsenleft >= 0) 9200 if (--parsenleft >= 0)
9195 return signed_char2int(*parsenextc++); 9201 return signed_char2int(*parsenextc++);
9196 } 9202 }
9197 if (parsenleft == EOF_NLEFT || g_parsefile->buf == NULL) 9203 /* on both branches above parsenleft < 0.
9204 * "pgetc" needs refilling.
9205 */
9206
9207 /* -90 is -BIGNUM. Below we use -99 to mark "EOF on read",
9208 * pungetc() may decrement it a few times. -90 is enough.
9209 */
9210 if (parsenleft < -90 || g_parsefile->buf == NULL) {
9211 pgetc_debug("preadbuffer PEOF1");
9212 /* even in failure keep them in lock step,
9213 * for correct pungetc. */
9214 parsenextc++;
9198 return PEOF; 9215 return PEOF;
9199 flush_stdout_stderr(); 9216 }
9200 9217
9201 more = parselleft; 9218 more = parselleft;
9202 if (more <= 0) { 9219 if (more <= 0) {
9220 flush_stdout_stderr();
9203 again: 9221 again:
9204 more = preadfd(); 9222 more = preadfd();
9205 if (more <= 0) { 9223 if (more <= 0) {
9206 parselleft = parsenleft = EOF_NLEFT; 9224 parselleft = parsenleft = -99;
9225 pgetc_debug("preadbuffer PEOF2");
9226 parsenextc++;
9207 return PEOF; 9227 return PEOF;
9208 } 9228 }
9209 } 9229 }
9210 9230
9231 /* Find out where's the end of line.
9232 * Set parsenleft/parselleft acordingly.
9233 * NUL chars are deleted.
9234 */
9211 q = parsenextc; 9235 q = parsenextc;
9212
9213 /* delete nul characters */
9214 for (;;) { 9236 for (;;) {
9215 int c; 9237 char c;
9216 9238
9217 more--; 9239 more--;
9218 c = *q;
9219 9240
9220 if (!c) 9241 c = *q;
9242 if (c == '\0') {
9221 memmove(q, q + 1, more); 9243 memmove(q, q + 1, more);
9222 else { 9244 } else {
9223 q++; 9245 q++;
9224 if (c == '\n') { 9246 if (c == '\n') {
9225 parsenleft = q - parsenextc - 1; 9247 parsenleft = q - parsenextc - 1;
@@ -9236,22 +9258,23 @@ preadbuffer(void)
9236 } 9258 }
9237 parselleft = more; 9259 parselleft = more;
9238 9260
9239 savec = *q;
9240 *q = '\0';
9241
9242 if (vflag) { 9261 if (vflag) {
9262 char save = *q;
9263 *q = '\0';
9243 out2str(parsenextc); 9264 out2str(parsenextc);
9265 *q = save;
9244 } 9266 }
9245 9267
9246 *q = savec; 9268 pgetc_debug("preadbuffer at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
9247
9248 return signed_char2int(*parsenextc++); 9269 return signed_char2int(*parsenextc++);
9249} 9270}
9250 9271
9251#define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer()) 9272#define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer())
9273
9252static int 9274static int
9253pgetc(void) 9275pgetc(void)
9254{ 9276{
9277 pgetc_debug("pgetc at %d:%p'%s'", parsenleft, parsenextc, parsenextc);
9255 return pgetc_as_macro(); 9278 return pgetc_as_macro();
9256} 9279}
9257 9280
@@ -9312,6 +9335,7 @@ pungetc(void)
9312{ 9335{
9313 parsenleft++; 9336 parsenleft++;
9314 parsenextc--; 9337 parsenextc--;
9338 pgetc_debug("pushed back to %d:%p'%s'", parsenleft, parsenextc, parsenextc);
9315} 9339}
9316 9340
9317/* 9341/*
@@ -9325,16 +9349,17 @@ static void
9325pushstring(char *s, struct alias *ap) 9349pushstring(char *s, struct alias *ap)
9326{ 9350{
9327 struct strpush *sp; 9351 struct strpush *sp;
9328 size_t len; 9352 int len;
9329 9353
9330 len = strlen(s); 9354 len = strlen(s);
9331 INT_OFF; 9355 INT_OFF;
9332 if (g_parsefile->strpush) { 9356 if (g_parsefile->strpush) {
9333 sp = ckzalloc(sizeof(struct strpush)); 9357 sp = ckzalloc(sizeof(*sp));
9334 sp->prev = g_parsefile->strpush; 9358 sp->prev = g_parsefile->strpush;
9335 g_parsefile->strpush = sp; 9359 } else {
9336 } else 9360 sp = &(g_parsefile->basestrpush);
9337 sp = g_parsefile->strpush = &(g_parsefile->basestrpush); 9361 }
9362 g_parsefile->strpush = sp;
9338 sp->prevstring = parsenextc; 9363 sp->prevstring = parsenextc;
9339 sp->prevnleft = parsenleft; 9364 sp->prevnleft = parsenleft;
9340#if ENABLE_ASH_ALIAS 9365#if ENABLE_ASH_ALIAS
@@ -9424,7 +9449,7 @@ setinputfd(int fd, int push)
9424 close_on_exec_on(fd); 9449 close_on_exec_on(fd);
9425 if (push) { 9450 if (push) {
9426 pushfile(); 9451 pushfile();
9427 g_parsefile->buf = 0; 9452 g_parsefile->buf = NULL;
9428 } 9453 }
9429 g_parsefile->fd = fd; 9454 g_parsefile->fd = fd;
9430 if (g_parsefile->buf == NULL) 9455 if (g_parsefile->buf == NULL)