diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-29 06:49:36 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-29 06:49:36 +0000 |
commit | ab310e1b1c2f85235e61c471802b53314da919f0 (patch) | |
tree | 415cf40159a0c2b6009a27df18b0cc45bea2e956 /shell | |
parent | 1cd1012a9063656a6b5b75dac8d400abd60cd643 (diff) | |
download | busybox-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.c | 147 |
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 | ||
540 | union node; | 541 | union 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 | ||
7549 | static int funcblocksize; /* size of structures in function */ | 7550 | static int funcblocksize; /* size of structures in function */ |
7550 | static int funcstringsize; /* size of strings in node */ | 7551 | static int funcstringsize; /* size of strings in node */ |
7551 | static void *funcblock; /* block to allocate function from */ | 7552 | static void *funcblock; /* block to allocate function from */ |
7552 | static char *funcstring; /* block to allocate strings from */ | 7553 | static 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 | ||
7559 | static const short nodesize[26] = { | 7560 | static 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 | ||
7588 | static void calcsize(union node *n); | 7592 | static 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 | |||
9070 | enum { | 9072 | enum { |
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) | ||
9179 | static int | 9182 | static int |
9180 | preadbuffer(void) | 9183 | preadbuffer(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 | |||
9252 | static int | 9274 | static int |
9253 | pgetc(void) | 9275 | pgetc(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 | |||
9325 | pushstring(char *s, struct alias *ap) | 9349 | pushstring(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) |