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>
This commit is contained in:
parent
897475ab02
commit
f3634584d0
62
shell/ash.c
62
shell/ash.c
@ -315,17 +315,18 @@ static const char *const optletters_optnames[] = {
|
|||||||
"e" "errexit",
|
"e" "errexit",
|
||||||
"f" "noglob",
|
"f" "noglob",
|
||||||
"I" "ignoreeof",
|
"I" "ignoreeof",
|
||||||
/* The below allows this invocation:
|
/* The below allowed this invocation:
|
||||||
* ash -c 'set -i; echo $-; sleep 5; echo $-'
|
* ash -c 'set -i; echo $-; sleep 5; echo $-'
|
||||||
* to be ^C-ed and get to interactive ash prompt.
|
* to be ^C-ed and get to interactive ash prompt.
|
||||||
* bash does not support this "set -i". bash also has no
|
* bash does not support such "set -i".
|
||||||
* "set -o interactive".
|
* In our code, this is denoted by empty long name:
|
||||||
*/
|
*/
|
||||||
"i" "interactive",
|
"i" "",
|
||||||
"m" "monitor",
|
"m" "monitor",
|
||||||
"n" "noexec",
|
"n" "noexec",
|
||||||
/* Ditto: bash has no "set -s" and "set -o stdin" */
|
/* Ditto: bash has no "set -s" */
|
||||||
"s" "stdin",
|
"s" "",
|
||||||
|
"c" "",
|
||||||
"x" "xtrace",
|
"x" "xtrace",
|
||||||
"v" "verbose",
|
"v" "verbose",
|
||||||
"C" "noclobber",
|
"C" "noclobber",
|
||||||
@ -359,7 +360,6 @@ static const char *const optletters_optnames[] = {
|
|||||||
#define optletters(n) optletters_optnames[n][0]
|
#define optletters(n) optletters_optnames[n][0]
|
||||||
#define optnames(n) (optletters_optnames[n] + 1)
|
#define optnames(n) (optletters_optnames[n] + 1)
|
||||||
|
|
||||||
|
|
||||||
enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
|
enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
|
||||||
|
|
||||||
|
|
||||||
@ -419,21 +419,22 @@ struct globals_misc {
|
|||||||
#define mflag optlist[4]
|
#define mflag optlist[4]
|
||||||
#define nflag optlist[5]
|
#define nflag optlist[5]
|
||||||
#define sflag optlist[6]
|
#define sflag optlist[6]
|
||||||
#define xflag optlist[7]
|
#define cflag optlist[7]
|
||||||
#define vflag optlist[8]
|
#define xflag optlist[8]
|
||||||
#define Cflag optlist[9]
|
#define vflag optlist[9]
|
||||||
#define aflag optlist[10]
|
#define Cflag optlist[10]
|
||||||
#define bflag optlist[11]
|
#define aflag optlist[11]
|
||||||
#define uflag optlist[12]
|
#define bflag optlist[12]
|
||||||
#define viflag optlist[13]
|
#define uflag optlist[13]
|
||||||
|
#define viflag optlist[14]
|
||||||
#if BASH_PIPEFAIL
|
#if BASH_PIPEFAIL
|
||||||
# define pipefail optlist[14]
|
# define pipefail optlist[15]
|
||||||
#else
|
#else
|
||||||
# define pipefail 0
|
# define pipefail 0
|
||||||
#endif
|
#endif
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
# define nolog optlist[14 + BASH_PIPEFAIL]
|
# define nolog optlist[15 + BASH_PIPEFAIL]
|
||||||
# define debug optlist[15 + BASH_PIPEFAIL]
|
# define debug optlist[16 + BASH_PIPEFAIL]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* trap handler commands */
|
/* trap handler commands */
|
||||||
@ -11104,7 +11105,7 @@ setoption(int flag, int val)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NOPTS; i++) {
|
for (i = 0; i < NOPTS; i++) {
|
||||||
if (optletters(i) == flag) {
|
if (optletters(i) == flag && optnames(i)[0] != '\0') {
|
||||||
optlist[i] = val;
|
optlist[i] = val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -11150,6 +11151,15 @@ options(int *login_sh)
|
|||||||
/* bash 3.2 indeed handles -c CMD and +c CMD the same */
|
/* bash 3.2 indeed handles -c CMD and +c CMD the same */
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
minusc = p; /* command is after shell args */
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == 'l') {
|
if (c == 'l') {
|
||||||
@ -14170,8 +14180,13 @@ procargs(char **argv)
|
|||||||
ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
|
ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
|
||||||
sflag = 1;
|
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;
|
iflag = 1;
|
||||||
|
}
|
||||||
if (mflag == 2)
|
if (mflag == 2)
|
||||||
mflag = iflag;
|
mflag = iflag;
|
||||||
for (i = 0; i < NOPTS; i++)
|
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)
|
* Ensure we don't falsely claim that 0 (stdin)
|
||||||
* is one of stacked source fds.
|
* is one of stacked source fds.
|
||||||
* Testcase: ash -c 'exec 1>&0' must not complain. */
|
* Testcase: ash -c 'exec 1>&0' must not complain. */
|
||||||
|
|
||||||
// if (!sflag) g_parsefile->pf_fd = -1;
|
// if (!sflag) g_parsefile->pf_fd = -1;
|
||||||
// ^^ not necessary since now we special-case fd 0
|
// ^^ not necessary since now we special-case fd 0
|
||||||
// in save_fd_on_redirect()
|
// 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) {
|
if (sflag || minusc == NULL) {
|
||||||
|
13
shell/hush.c
13
shell/hush.c
@ -903,6 +903,7 @@ struct globals {
|
|||||||
# define G_x_mode 0
|
# define G_x_mode 0
|
||||||
#endif
|
#endif
|
||||||
char opt_s;
|
char opt_s;
|
||||||
|
char opt_c;
|
||||||
#if ENABLE_HUSH_INTERACTIVE
|
#if ENABLE_HUSH_INTERACTIVE
|
||||||
smallint promptmode; /* 0: PS1, 1: PS2 */
|
smallint promptmode; /* 0: PS1, 1: PS2 */
|
||||||
#endif
|
#endif
|
||||||
@ -1009,7 +1010,7 @@ struct globals {
|
|||||||
int debug_indent;
|
int debug_indent;
|
||||||
#endif
|
#endif
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
char optstring_buf[sizeof("eixs")];
|
char optstring_buf[sizeof("eixcs")];
|
||||||
#if BASH_EPOCH_VARS
|
#if BASH_EPOCH_VARS
|
||||||
char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
|
char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
|
||||||
#endif
|
#endif
|
||||||
@ -6414,9 +6415,10 @@ static NOINLINE int expand_one_var(o_string *output, int n,
|
|||||||
* commands read but are not executed,
|
* commands read but are not executed,
|
||||||
* so $- can not execute too, 'n' is never seen in $-.
|
* so $- can not execute too, 'n' is never seen in $-.
|
||||||
*/
|
*/
|
||||||
|
if (G.opt_c)
|
||||||
|
*cp++ = 'c';
|
||||||
if (G.opt_s)
|
if (G.opt_s)
|
||||||
*cp++ = 's';
|
*cp++ = 's';
|
||||||
//TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash)
|
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -9859,7 +9861,6 @@ int hush_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
OPT_login = (1 << 0),
|
OPT_login = (1 << 0),
|
||||||
OPT_s = (1 << 1),
|
|
||||||
};
|
};
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
unsigned builtin_argc;
|
unsigned builtin_argc;
|
||||||
@ -10029,6 +10030,7 @@ int hush_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
goto final_return;
|
goto final_return;
|
||||||
}
|
}
|
||||||
|
G.opt_c = 1;
|
||||||
if (!G.global_argv[0]) {
|
if (!G.global_argv[0]) {
|
||||||
/* -c 'script' (no params): prevent empty $0 */
|
/* -c 'script' (no params): prevent empty $0 */
|
||||||
G.global_argv--; /* points to argv[i] of 'script' */
|
G.global_argv--; /* points to argv[i] of 'script' */
|
||||||
@ -10044,7 +10046,7 @@ int hush_main(int argc, char **argv)
|
|||||||
/* G_interactive_fd++; */
|
/* G_interactive_fd++; */
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
flags |= OPT_s;
|
G.opt_s = 1;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
flags |= OPT_login;
|
flags |= OPT_login;
|
||||||
@ -10154,7 +10156,7 @@ int hush_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
|
/* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
|
||||||
if (!(flags & OPT_s) && G.global_argv[1]) {
|
if (!G.opt_s && G.global_argv[1]) {
|
||||||
HFILE *input;
|
HFILE *input;
|
||||||
/*
|
/*
|
||||||
* "bash <script>" (which is never interactive (unless -i?))
|
* "bash <script>" (which is never interactive (unless -i?))
|
||||||
@ -10178,6 +10180,7 @@ int hush_main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
goto final_return;
|
goto final_return;
|
||||||
}
|
}
|
||||||
|
/* "implicit" -s: bare interactive hush shows 's' in $- */
|
||||||
G.opt_s = 1;
|
G.opt_s = 1;
|
||||||
|
|
||||||
/* Up to here, shell was non-interactive. Now it may become one.
|
/* Up to here, shell was non-interactive. Now it may become one.
|
||||||
|
Loading…
Reference in New Issue
Block a user