aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c62
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
363enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; 363enum { 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) {