diff options
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/shell/ash.c b/shell/ash.c index c8857366c..e3bbac9a0 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -315,17 +315,18 @@ static const char *const optletters_optnames[] = { | |||
315 | "e" "errexit", | 315 | "e" "errexit", |
316 | "f" "noglob", | 316 | "f" "noglob", |
317 | "I" "ignoreeof", | 317 | "I" "ignoreeof", |
318 | /* The below allows this invocation: | 318 | /* The below allowed this invocation: |
319 | * ash -c 'set -i; echo $-; sleep 5; echo $-' | 319 | * ash -c 'set -i; echo $-; sleep 5; echo $-' |
320 | * to be ^C-ed and get to interactive ash prompt. | 320 | * to be ^C-ed and get to interactive ash prompt. |
321 | * bash does not support this "set -i". bash also has no | 321 | * bash does not support such "set -i". |
322 | * "set -o interactive". | 322 | * In our code, this is denoted by empty long name: |
323 | */ | 323 | */ |
324 | "i" "interactive", | 324 | "i" "", |
325 | "m" "monitor", | 325 | "m" "monitor", |
326 | "n" "noexec", | 326 | "n" "noexec", |
327 | /* Ditto: bash has no "set -s" and "set -o stdin" */ | 327 | /* Ditto: bash has no "set -s" */ |
328 | "s" "stdin", | 328 | "s" "", |
329 | "c" "", | ||
329 | "x" "xtrace", | 330 | "x" "xtrace", |
330 | "v" "verbose", | 331 | "v" "verbose", |
331 | "C" "noclobber", | 332 | "C" "noclobber", |
@@ -359,7 +360,6 @@ static const char *const optletters_optnames[] = { | |||
359 | #define optletters(n) optletters_optnames[n][0] | 360 | #define optletters(n) optletters_optnames[n][0] |
360 | #define optnames(n) (optletters_optnames[n] + 1) | 361 | #define optnames(n) (optletters_optnames[n] + 1) |
361 | 362 | ||
362 | |||
363 | enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; | 363 | enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; |
364 | 364 | ||
365 | 365 | ||
@@ -419,21 +419,22 @@ struct globals_misc { | |||
419 | #define mflag optlist[4] | 419 | #define mflag optlist[4] |
420 | #define nflag optlist[5] | 420 | #define nflag optlist[5] |
421 | #define sflag optlist[6] | 421 | #define sflag optlist[6] |
422 | #define xflag optlist[7] | 422 | #define cflag optlist[7] |
423 | #define vflag optlist[8] | 423 | #define xflag optlist[8] |
424 | #define Cflag optlist[9] | 424 | #define vflag optlist[9] |
425 | #define aflag optlist[10] | 425 | #define Cflag optlist[10] |
426 | #define bflag optlist[11] | 426 | #define aflag optlist[11] |
427 | #define uflag optlist[12] | 427 | #define bflag optlist[12] |
428 | #define viflag optlist[13] | 428 | #define uflag optlist[13] |
429 | #define viflag optlist[14] | ||
429 | #if BASH_PIPEFAIL | 430 | #if BASH_PIPEFAIL |
430 | # define pipefail optlist[14] | 431 | # define pipefail optlist[15] |
431 | #else | 432 | #else |
432 | # define pipefail 0 | 433 | # define pipefail 0 |
433 | #endif | 434 | #endif |
434 | #if DEBUG | 435 | #if DEBUG |
435 | # define nolog optlist[14 + BASH_PIPEFAIL] | 436 | # define nolog optlist[15 + BASH_PIPEFAIL] |
436 | # define debug optlist[15 + BASH_PIPEFAIL] | 437 | # define debug optlist[16 + BASH_PIPEFAIL] |
437 | #endif | 438 | #endif |
438 | 439 | ||
439 | /* trap handler commands */ | 440 | /* trap handler commands */ |
@@ -11104,7 +11105,7 @@ setoption(int flag, int val) | |||
11104 | int i; | 11105 | int i; |
11105 | 11106 | ||
11106 | for (i = 0; i < NOPTS; i++) { | 11107 | for (i = 0; i < NOPTS; i++) { |
11107 | if (optletters(i) == flag) { | 11108 | if (optletters(i) == flag && optnames(i)[0] != '\0') { |
11108 | optlist[i] = val; | 11109 | optlist[i] = val; |
11109 | return; | 11110 | return; |
11110 | } | 11111 | } |
@@ -11150,6 +11151,15 @@ options(int *login_sh) | |||
11150 | /* bash 3.2 indeed handles -c CMD and +c CMD the same */ | 11151 | /* bash 3.2 indeed handles -c CMD and +c CMD the same */ |
11151 | if (c == 'c') { | 11152 | if (c == 'c') { |
11152 | minusc = p; /* command is after shell args */ | 11153 | minusc = p; /* command is after shell args */ |
11154 | cflag = 1; | ||
11155 | continue; | ||
11156 | } | ||
11157 | if (c == 's') { /* -s, +s */ | ||
11158 | sflag = 1; | ||
11159 | continue; | ||
11160 | } | ||
11161 | if (c == 'i') { /* -i, +i */ | ||
11162 | iflag = 1; | ||
11153 | continue; | 11163 | continue; |
11154 | } | 11164 | } |
11155 | if (c == 'l') { | 11165 | if (c == 'l') { |
@@ -14170,8 +14180,13 @@ procargs(char **argv) | |||
14170 | ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); | 14180 | ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); |
14171 | sflag = 1; | 14181 | sflag = 1; |
14172 | } | 14182 | } |
14173 | if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) | 14183 | if (iflag == 2 /* no explicit -i given */ |
14184 | && sflag == 1 /* -s given (or implied) */ | ||
14185 | && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */ | ||
14186 | && isatty(0) && isatty(1) /* we are on tty */ | ||
14187 | ) { | ||
14174 | iflag = 1; | 14188 | iflag = 1; |
14189 | } | ||
14175 | if (mflag == 2) | 14190 | if (mflag == 2) |
14176 | mflag = iflag; | 14191 | mflag = iflag; |
14177 | for (i = 0; i < NOPTS; i++) | 14192 | for (i = 0; i < NOPTS; i++) |
@@ -14359,10 +14374,17 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
14359 | * Ensure we don't falsely claim that 0 (stdin) | 14374 | * Ensure we don't falsely claim that 0 (stdin) |
14360 | * is one of stacked source fds. | 14375 | * is one of stacked source fds. |
14361 | * Testcase: ash -c 'exec 1>&0' must not complain. */ | 14376 | * Testcase: ash -c 'exec 1>&0' must not complain. */ |
14377 | |||
14362 | // if (!sflag) g_parsefile->pf_fd = -1; | 14378 | // if (!sflag) g_parsefile->pf_fd = -1; |
14363 | // ^^ not necessary since now we special-case fd 0 | 14379 | // ^^ not necessary since now we special-case fd 0 |
14364 | // in save_fd_on_redirect() | 14380 | // in save_fd_on_redirect() |
14365 | evalstring(minusc, sflag ? 0 : EV_EXIT); | 14381 | |
14382 | // dash: evalstring(minusc, sflag ? 0 : EV_EXIT); | ||
14383 | // The above makes | ||
14384 | // ash -sc 'echo $-' | ||
14385 | // continue reading input from stdin after running 'echo'. | ||
14386 | // bash does not do this: it prints "hBcs" and exits. | ||
14387 | evalstring(minusc, EV_EXIT); | ||
14366 | } | 14388 | } |
14367 | 14389 | ||
14368 | if (sflag || minusc == NULL) { | 14390 | if (sflag || minusc == NULL) { |