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 c885736..e3bbac9 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -315,17 +315,18 @@ static const char *const optletters_optnames[] = { "e" "errexit", "f" "noglob", "I" "ignoreeof", -/* The below allows this invocation: +/* The below allowed this invocation: * ash -c 'set -i; echo $-; sleep 5; echo $-' * to be ^C-ed and get to interactive ash prompt. - * bash does not support this "set -i". bash also has no - * "set -o interactive". + * bash does not support such "set -i". + * In our code, this is denoted by empty long name: */ - "i" "interactive", + "i" "", "m" "monitor", "n" "noexec", -/* Ditto: bash has no "set -s" and "set -o stdin" */ - "s" "stdin", +/* Ditto: bash has no "set -s" */ + "s" "", + "c" "", "x" "xtrace", "v" "verbose", "C" "noclobber", @@ -359,7 +360,6 @@ static const char *const optletters_optnames[] = { #define optletters(n) optletters_optnames[n][0] #define optnames(n) (optletters_optnames[n] + 1) - enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; @@ -419,21 +419,22 @@ struct globals_misc { #define mflag optlist[4] #define nflag optlist[5] #define sflag optlist[6] -#define xflag optlist[7] -#define vflag optlist[8] -#define Cflag optlist[9] -#define aflag optlist[10] -#define bflag optlist[11] -#define uflag optlist[12] -#define viflag optlist[13] +#define cflag optlist[7] +#define xflag optlist[8] +#define vflag optlist[9] +#define Cflag optlist[10] +#define aflag optlist[11] +#define bflag optlist[12] +#define uflag optlist[13] +#define viflag optlist[14] #if BASH_PIPEFAIL -# define pipefail optlist[14] +# define pipefail optlist[15] #else # define pipefail 0 #endif #if DEBUG -# define nolog optlist[14 + BASH_PIPEFAIL] -# define debug optlist[15 + BASH_PIPEFAIL] +# define nolog optlist[15 + BASH_PIPEFAIL] +# define debug optlist[16 + BASH_PIPEFAIL] #endif /* trap handler commands */ @@ -11104,7 +11105,7 @@ setoption(int flag, int val) int i; for (i = 0; i < NOPTS; i++) { - if (optletters(i) == flag) { + if (optletters(i) == flag && optnames(i)[0] != '\0') { optlist[i] = val; return; } @@ -11150,6 +11151,15 @@ options(int *login_sh) /* bash 3.2 indeed handles -c CMD and +c CMD the same */ if (c == 'c') { minusc = p; /* command is after shell args */ + cflag = 1; + continue; + } + if (c == 's') { /* -s, +s */ + sflag = 1; + continue; + } + if (c == 'i') { /* -i, +i */ + iflag = 1; continue; } if (c == 'l') { @@ -14170,8 +14180,13 @@ procargs(char **argv) ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); sflag = 1; } - if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) + if (iflag == 2 /* no explicit -i given */ + && sflag == 1 /* -s given (or implied) */ + && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */ + && isatty(0) && isatty(1) /* we are on tty */ + ) { iflag = 1; + } if (mflag == 2) mflag = iflag; for (i = 0; i < NOPTS; i++) @@ -14359,10 +14374,17 @@ int ash_main(int argc UNUSED_PARAM, char **argv) * Ensure we don't falsely claim that 0 (stdin) * is one of stacked source fds. * Testcase: ash -c 'exec 1>&0' must not complain. */ + // if (!sflag) g_parsefile->pf_fd = -1; // ^^ not necessary since now we special-case fd 0 // in save_fd_on_redirect() - evalstring(minusc, sflag ? 0 : EV_EXIT); + + // dash: evalstring(minusc, sflag ? 0 : EV_EXIT); + // The above makes + // ash -sc 'echo $-' + // continue reading input from stdin after running 'echo'. + // bash does not do this: it prints "hBcs" and exits. + evalstring(minusc, EV_EXIT); } if (sflag || minusc == NULL) { |