aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-06-03 12:21:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-06-03 12:21:04 +0200
commitf3634584d0fdeb4ae9e2fe0f5971d45b77e40296 (patch)
tree28a97129b30b28106b4f9fae7ddfbc5be12ba0f6
parent897475ab023040efed9f199af5daffe43451c1d2 (diff)
downloadbusybox-w32-f3634584d0fdeb4ae9e2fe0f5971d45b77e40296.tar.gz
busybox-w32-f3634584d0fdeb4ae9e2fe0f5971d45b77e40296.tar.bz2
busybox-w32-f3634584d0fdeb4ae9e2fe0f5971d45b77e40296.zip
ash,hush: show 'c' in $- if run in "sh -c CMD"
function old new delta options 552 599 +47 expand_one_var 2375 2385 +10 optletters_optnames 60 64 +4 hush_main 1108 1111 +3 ash_main 1150 1152 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 66/0) Total: 66 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c62
-rw-r--r--shell/hush.c13
2 files changed, 50 insertions, 25 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) {
diff --git a/shell/hush.c b/shell/hush.c
index 4b08232a4..f82747f74 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -903,6 +903,7 @@ struct globals {
903# define G_x_mode 0 903# define G_x_mode 0
904#endif 904#endif
905 char opt_s; 905 char opt_s;
906 char opt_c;
906#if ENABLE_HUSH_INTERACTIVE 907#if ENABLE_HUSH_INTERACTIVE
907 smallint promptmode; /* 0: PS1, 1: PS2 */ 908 smallint promptmode; /* 0: PS1, 1: PS2 */
908#endif 909#endif
@@ -1009,7 +1010,7 @@ struct globals {
1009 int debug_indent; 1010 int debug_indent;
1010#endif 1011#endif
1011 struct sigaction sa; 1012 struct sigaction sa;
1012 char optstring_buf[sizeof("eixs")]; 1013 char optstring_buf[sizeof("eixcs")];
1013#if BASH_EPOCH_VARS 1014#if BASH_EPOCH_VARS
1014 char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; 1015 char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
1015#endif 1016#endif
@@ -6414,9 +6415,10 @@ static NOINLINE int expand_one_var(o_string *output, int n,
6414 * commands read but are not executed, 6415 * commands read but are not executed,
6415 * so $- can not execute too, 'n' is never seen in $-. 6416 * so $- can not execute too, 'n' is never seen in $-.
6416 */ 6417 */
6418 if (G.opt_c)
6419 *cp++ = 'c';
6417 if (G.opt_s) 6420 if (G.opt_s)
6418 *cp++ = 's'; 6421 *cp++ = 's';
6419//TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash)
6420 *cp = '\0'; 6422 *cp = '\0';
6421 break; 6423 break;
6422 } 6424 }
@@ -9859,7 +9861,6 @@ int hush_main(int argc, char **argv)
9859{ 9861{
9860 enum { 9862 enum {
9861 OPT_login = (1 << 0), 9863 OPT_login = (1 << 0),
9862 OPT_s = (1 << 1),
9863 }; 9864 };
9864 unsigned flags; 9865 unsigned flags;
9865 unsigned builtin_argc; 9866 unsigned builtin_argc;
@@ -10029,6 +10030,7 @@ int hush_main(int argc, char **argv)
10029 } 10030 }
10030 goto final_return; 10031 goto final_return;
10031 } 10032 }
10033 G.opt_c = 1;
10032 if (!G.global_argv[0]) { 10034 if (!G.global_argv[0]) {
10033 /* -c 'script' (no params): prevent empty $0 */ 10035 /* -c 'script' (no params): prevent empty $0 */
10034 G.global_argv--; /* points to argv[i] of 'script' */ 10036 G.global_argv--; /* points to argv[i] of 'script' */
@@ -10044,7 +10046,7 @@ int hush_main(int argc, char **argv)
10044 /* G_interactive_fd++; */ 10046 /* G_interactive_fd++; */
10045 break; 10047 break;
10046 case 's': 10048 case 's':
10047 flags |= OPT_s; 10049 G.opt_s = 1;
10048 break; 10050 break;
10049 case 'l': 10051 case 'l':
10050 flags |= OPT_login; 10052 flags |= OPT_login;
@@ -10154,7 +10156,7 @@ int hush_main(int argc, char **argv)
10154 } 10156 }
10155 10157
10156 /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ 10158 /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
10157 if (!(flags & OPT_s) && G.global_argv[1]) { 10159 if (!G.opt_s && G.global_argv[1]) {
10158 HFILE *input; 10160 HFILE *input;
10159 /* 10161 /*
10160 * "bash <script>" (which is never interactive (unless -i?)) 10162 * "bash <script>" (which is never interactive (unless -i?))
@@ -10178,6 +10180,7 @@ int hush_main(int argc, char **argv)
10178#endif 10180#endif
10179 goto final_return; 10181 goto final_return;
10180 } 10182 }
10183 /* "implicit" -s: bare interactive hush shows 's' in $- */
10181 G.opt_s = 1; 10184 G.opt_s = 1;
10182 10185
10183 /* Up to here, shell was non-interactive. Now it may become one. 10186 /* Up to here, shell was non-interactive. Now it may become one.