ash: allocate line editing structure only if needed
function old new delta optschanged 91 128 +37 historycmd 13 17 +4 setcmd 80 78 -2 ash_main 1167 1150 -17 options 576 552 -24 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/3 up/down: 41/-43) Total: -2 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
6eb6e6a1e9
commit
897475ab02
107
shell/ash.c
107
shell/ash.c
@ -315,9 +315,16 @@ static const char *const optletters_optnames[] = {
|
|||||||
"e" "errexit",
|
"e" "errexit",
|
||||||
"f" "noglob",
|
"f" "noglob",
|
||||||
"I" "ignoreeof",
|
"I" "ignoreeof",
|
||||||
|
/* The below allows 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".
|
||||||
|
*/
|
||||||
"i" "interactive",
|
"i" "interactive",
|
||||||
"m" "monitor",
|
"m" "monitor",
|
||||||
"n" "noexec",
|
"n" "noexec",
|
||||||
|
/* Ditto: bash has no "set -s" and "set -o stdin" */
|
||||||
"s" "stdin",
|
"s" "stdin",
|
||||||
"x" "xtrace",
|
"x" "xtrace",
|
||||||
"v" "verbose",
|
"v" "verbose",
|
||||||
@ -334,10 +341,25 @@ static const char *const optletters_optnames[] = {
|
|||||||
,"\0" "debug"
|
,"\0" "debug"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
//bash 4.4.23 also has these opts (with these defaults):
|
||||||
|
//braceexpand on
|
||||||
|
//emacs on
|
||||||
|
//errtrace off
|
||||||
|
//functrace off
|
||||||
|
//hashall on
|
||||||
|
//histexpand off
|
||||||
|
//history on
|
||||||
|
//interactive-comments on
|
||||||
|
//keyword off
|
||||||
|
//onecmd off
|
||||||
|
//physical off
|
||||||
|
//posix off
|
||||||
|
//privileged off
|
||||||
|
|
||||||
#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) };
|
||||||
|
|
||||||
|
|
||||||
@ -9514,8 +9536,8 @@ setinteractive(int on)
|
|||||||
setsignal(SIGINT);
|
setsignal(SIGINT);
|
||||||
setsignal(SIGQUIT);
|
setsignal(SIGQUIT);
|
||||||
setsignal(SIGTERM);
|
setsignal(SIGTERM);
|
||||||
#if !ENABLE_FEATURE_SH_EXTRA_QUIET
|
|
||||||
if (is_interactive > 1) {
|
if (is_interactive > 1) {
|
||||||
|
#if !ENABLE_FEATURE_SH_EXTRA_QUIET
|
||||||
/* Looks like they want an interactive shell */
|
/* Looks like they want an interactive shell */
|
||||||
static smallint did_banner;
|
static smallint did_banner;
|
||||||
|
|
||||||
@ -9529,8 +9551,12 @@ setinteractive(int on)
|
|||||||
);
|
);
|
||||||
did_banner = 1;
|
did_banner = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_FEATURE_EDITING
|
||||||
|
if (!line_input_state)
|
||||||
|
line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -9542,10 +9568,12 @@ optschanged(void)
|
|||||||
setinteractive(iflag);
|
setinteractive(iflag);
|
||||||
setjobctl(mflag);
|
setjobctl(mflag);
|
||||||
#if ENABLE_FEATURE_EDITING_VI
|
#if ENABLE_FEATURE_EDITING_VI
|
||||||
if (viflag)
|
if (line_input_state) {
|
||||||
line_input_state->flags |= VI_MODE;
|
if (viflag)
|
||||||
else
|
line_input_state->flags |= VI_MODE;
|
||||||
line_input_state->flags &= ~VI_MODE;
|
else
|
||||||
|
line_input_state->flags &= ~VI_MODE;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
viflag = 0; /* forcibly keep the option off */
|
viflag = 0; /* forcibly keep the option off */
|
||||||
#endif
|
#endif
|
||||||
@ -10519,13 +10547,11 @@ preadfd(void)
|
|||||||
else {
|
else {
|
||||||
# if ENABLE_ASH_IDLE_TIMEOUT
|
# if ENABLE_ASH_IDLE_TIMEOUT
|
||||||
int timeout = -1;
|
int timeout = -1;
|
||||||
if (iflag) {
|
const char *tmout_var = lookupvar("TMOUT");
|
||||||
const char *tmout_var = lookupvar("TMOUT");
|
if (tmout_var) {
|
||||||
if (tmout_var) {
|
timeout = atoi(tmout_var) * 1000;
|
||||||
timeout = atoi(tmout_var) * 1000;
|
if (timeout <= 0)
|
||||||
if (timeout <= 0)
|
timeout = -1;
|
||||||
timeout = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
line_input_state->timeout = timeout;
|
line_input_state->timeout = timeout;
|
||||||
# endif
|
# endif
|
||||||
@ -11086,14 +11112,17 @@ setoption(int flag, int val)
|
|||||||
ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
|
ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
/* If login_sh is not NULL, we are called to parse command line opts,
|
||||||
|
* not "set -opts"
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
options(int cmdline, int *login_sh)
|
options(int *login_sh)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int val;
|
int val;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (cmdline)
|
if (login_sh)
|
||||||
minusc = NULL;
|
minusc = NULL;
|
||||||
while ((p = *argptr) != NULL) {
|
while ((p = *argptr) != NULL) {
|
||||||
c = *p++;
|
c = *p++;
|
||||||
@ -11104,7 +11133,7 @@ options(int cmdline, int *login_sh)
|
|||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
val = 1;
|
val = 1;
|
||||||
if (p[0] == '\0' || LONE_DASH(p)) {
|
if (p[0] == '\0' || LONE_DASH(p)) {
|
||||||
if (!cmdline) {
|
if (!login_sh) {
|
||||||
/* "-" means turn off -x and -v */
|
/* "-" means turn off -x and -v */
|
||||||
if (p[0] == '\0')
|
if (p[0] == '\0')
|
||||||
xflag = vflag = 0;
|
xflag = vflag = 0;
|
||||||
@ -11117,26 +11146,31 @@ options(int cmdline, int *login_sh)
|
|||||||
}
|
}
|
||||||
/* first char was + or - */
|
/* first char was + or - */
|
||||||
while ((c = *p++) != '\0') {
|
while ((c = *p++) != '\0') {
|
||||||
/* bash 3.2 indeed handles -c CMD and +c CMD the same */
|
if (login_sh) {
|
||||||
if (c == 'c' && cmdline) {
|
/* bash 3.2 indeed handles -c CMD and +c CMD the same */
|
||||||
minusc = p; /* command is after shell args */
|
if (c == 'c') {
|
||||||
} else if (c == 'o') {
|
minusc = p; /* command is after shell args */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == 'l') {
|
||||||
|
*login_sh = 1; /* -l or +l == --login */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* bash does not accept +-login, we also won't */
|
||||||
|
if (val && (c == '-')) { /* long options */
|
||||||
|
if (strcmp(p, "login") == 0) {
|
||||||
|
*login_sh = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == 'o') {
|
||||||
if (plus_minus_o(*argptr, val)) {
|
if (plus_minus_o(*argptr, val)) {
|
||||||
/* it already printed err message */
|
/* it already printed err message */
|
||||||
return 1; /* error */
|
return 1; /* error */
|
||||||
}
|
}
|
||||||
if (*argptr)
|
if (*argptr)
|
||||||
argptr++;
|
argptr++;
|
||||||
} else if (cmdline && (c == 'l')) { /* -l or +l == --login */
|
|
||||||
if (login_sh)
|
|
||||||
*login_sh = 1;
|
|
||||||
/* bash does not accept +-login, we also won't */
|
|
||||||
} else if (cmdline && val && (c == '-')) { /* long options */
|
|
||||||
if (strcmp(p, "login") == 0) {
|
|
||||||
if (login_sh)
|
|
||||||
*login_sh = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
setoption(c, val);
|
setoption(c, val);
|
||||||
}
|
}
|
||||||
@ -11227,7 +11261,7 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
return showvars(nullstr, 0, VUNSET);
|
return showvars(nullstr, 0, VUNSET);
|
||||||
|
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
retval = options(/*cmdline:*/ 0, NULL);
|
retval = options(/*login_sh:*/ NULL);
|
||||||
if (retval == 0) { /* if no parse error... */
|
if (retval == 0) { /* if no parse error... */
|
||||||
optschanged();
|
optschanged();
|
||||||
if (*argptr != NULL) {
|
if (*argptr != NULL) {
|
||||||
@ -13685,7 +13719,8 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
static int FAST_FUNC
|
static int FAST_FUNC
|
||||||
historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
show_history(line_input_state);
|
if (line_input_state)
|
||||||
|
show_history(line_input_state);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -14001,7 +14036,8 @@ exitshell(void)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
save_history(line_input_state);
|
if (line_input_state)
|
||||||
|
save_history(line_input_state);
|
||||||
#endif
|
#endif
|
||||||
status = exitstatus;
|
status = exitstatus;
|
||||||
TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
|
TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
|
||||||
@ -14123,7 +14159,7 @@ procargs(char **argv)
|
|||||||
argptr = xargv;
|
argptr = xargv;
|
||||||
for (i = 0; i < NOPTS; i++)
|
for (i = 0; i < NOPTS; i++)
|
||||||
optlist[i] = 2;
|
optlist[i] = 2;
|
||||||
if (options(/*cmdline:*/ 1, &login_sh)) {
|
if (options(&login_sh)) {
|
||||||
/* it already printed err message */
|
/* it already printed err message */
|
||||||
raise_exception(EXERROR);
|
raise_exception(EXERROR);
|
||||||
}
|
}
|
||||||
@ -14249,9 +14285,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
|
monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_FEATURE_EDITING
|
|
||||||
line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
|
|
||||||
#endif
|
|
||||||
state = 0;
|
state = 0;
|
||||||
if (setjmp(jmploc.loc)) {
|
if (setjmp(jmploc.loc)) {
|
||||||
smallint e;
|
smallint e;
|
||||||
|
Loading…
Reference in New Issue
Block a user