aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-05-16 15:39:19 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-05-16 15:39:19 +0200
commit4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8 (patch)
tree80503d42301ee7ff16368a4a2f94e2b9b165564c /shell
parenta51eec0b5aaee3835a54ca35c65e3cfc87004b97 (diff)
downloadbusybox-w32-4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8.tar.gz
busybox-w32-4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8.tar.bz2
busybox-w32-4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8.zip
hush: remove code to track PS1/2 values dynamically - it's too much work
Assignments / exports / unsets of variables are far more frequent than prompt printing, and if we show prompt, we are likely to be limited by user typing speed - do not optimize for that scenario. Just re-query $PS1 / $PS2 values when need to show the prompt. function old new delta fgetc_interactive 236 259 +23 set_vars_and_save_old 150 147 -3 pseudo_exec_argv 597 594 -3 hush_main 1110 1105 -5 enter_var_nest_level 38 32 -6 builtin_local 56 50 -6 run_pipe 1857 1834 -23 leave_var_nest_level 127 98 -29 handle_changed_special_names 111 79 -32 cmdedit_update_prompt 57 - -57 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/8 up/down: 23/-164) Total: -141 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c82
1 files changed, 21 insertions, 61 deletions
diff --git a/shell/hush.c b/shell/hush.c
index ce341632a..e2927afc4 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -854,8 +854,7 @@ struct globals {
854 /* 'interactive_fd' is a fd# open to ctty, if we have one 854 /* 'interactive_fd' is a fd# open to ctty, if we have one
855 * _AND_ if we decided to act interactively */ 855 * _AND_ if we decided to act interactively */
856 int interactive_fd; 856 int interactive_fd;
857 const char *PS1; 857 IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;)
858 IF_FEATURE_EDITING_FANCY_PROMPT(const char *PS2;)
859# define G_interactive_fd (G.interactive_fd) 858# define G_interactive_fd (G.interactive_fd)
860#else 859#else
861# define G_interactive_fd 0 860# define G_interactive_fd 0
@@ -1448,13 +1447,6 @@ static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1448#endif 1447#endif
1449 1448
1450 1449
1451#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
1452static void cmdedit_update_prompt(void);
1453#else
1454# define cmdedit_update_prompt() ((void)0)
1455#endif
1456
1457
1458/* Utility functions 1450/* Utility functions
1459 */ 1451 */
1460/* Replace each \x with x in place, return ptr past NUL. */ 1452/* Replace each \x with x in place, return ptr past NUL. */
@@ -2248,33 +2240,22 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
2248 return NULL; 2240 return NULL;
2249} 2241}
2250 2242
2251#if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT) \ 2243#if ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS
2252 || (ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
2253static void handle_changed_special_names(const char *name, unsigned name_len) 2244static void handle_changed_special_names(const char *name, unsigned name_len)
2254{ 2245{
2255 if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT 2246 if (name_len == 6) {
2256 && name_len == 3 && name[0] == 'P' && name[1] == 'S' 2247# if ENABLE_HUSH_LINENO_VAR
2257 ) {
2258 if (G_interactive_fd)
2259 cmdedit_update_prompt();
2260 return;
2261 }
2262
2263 if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
2264 && name_len == 6
2265 ) {
2266#if ENABLE_HUSH_LINENO_VAR
2267 if (strncmp(name, "LINENO", 6) == 0) { 2248 if (strncmp(name, "LINENO", 6) == 0) {
2268 G.lineno_var = NULL; 2249 G.lineno_var = NULL;
2269 return; 2250 return;
2270 } 2251 }
2271#endif 2252# endif
2272#if ENABLE_HUSH_GETOPTS 2253# if ENABLE_HUSH_GETOPTS
2273 if (strncmp(name, "OPTIND", 6) == 0) { 2254 if (strncmp(name, "OPTIND", 6) == 0) {
2274 G.getopt_count = 0; 2255 G.getopt_count = 0;
2275 return; 2256 return;
2276 } 2257 }
2277#endif 2258# endif
2278 } 2259 }
2279} 2260}
2280#else 2261#else
@@ -2470,7 +2451,7 @@ static int unset_local_var_len(const char *name, int name_len)
2470 cur_pp = &cur->next; 2451 cur_pp = &cur->next;
2471 } 2452 }
2472 2453
2473 /* Handle "unset PS1" et al even if did not find the variable to unset */ 2454 /* Handle "unset LINENO" et al even if did not find the variable to unset */
2474 handle_changed_special_names(name, name_len); 2455 handle_changed_special_names(name, name_len);
2475 2456
2476 return EXIT_SUCCESS; 2457 return EXIT_SUCCESS;
@@ -2500,11 +2481,6 @@ static void add_vars(struct variable *var)
2500 } else { 2481 } else {
2501 debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level); 2482 debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2502 } 2483 }
2503 /* Testcase (interactive):
2504 * f() { local PS1='\w \$ '; }; f
2505 * the below call is needed to notice restored PS1 when f returns.
2506 */
2507 handle_changed_special_names(var->varstr, endofname(var->varstr) - var->varstr);
2508 var = next; 2484 var = next;
2509 } 2485 }
2510} 2486}
@@ -2594,36 +2570,27 @@ static void reinit_unicode_for_hush(void)
2594 * \ 2570 * \
2595 * It exercises a lot of corner cases. 2571 * It exercises a lot of corner cases.
2596 */ 2572 */
2597# if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2598static void cmdedit_update_prompt(void)
2599{
2600 G.PS1 = get_local_var_value("PS1");
2601 if (G.PS1 == NULL)
2602 G.PS1 = "";
2603 G.PS2 = get_local_var_value("PS2");
2604 if (G.PS2 == NULL)
2605 G.PS2 = "";
2606}
2607# endif
2608static const char *setup_prompt_string(void) 2573static const char *setup_prompt_string(void)
2609{ 2574{
2610 const char *prompt_str; 2575 const char *prompt_str;
2611 2576
2612 debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode); 2577 debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2613 2578
2614 IF_FEATURE_EDITING_FANCY_PROMPT( prompt_str = G.PS2;) 2579# if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2615 IF_NOT_FEATURE_EDITING_FANCY_PROMPT(prompt_str = "> ";) 2580 prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2");
2581 if (!prompt_str)
2582 prompt_str = "";
2583# else
2584 prompt_str = "> "; /* if PS2, else... */
2616 if (G.promptmode == 0) { /* PS1 */ 2585 if (G.promptmode == 0) { /* PS1 */
2617 if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) { 2586 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2618 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */ 2587 free(G.PS1);
2619 free((char*)G.PS1); 2588 /* bash uses $PWD value, even if it is set by user.
2620 /* bash uses $PWD value, even if it is set by user. 2589 * It uses current dir only if PWD is unset.
2621 * It uses current dir only if PWD is unset. 2590 * We always use current dir. */
2622 * We always use current dir. */ 2591 G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2623 G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2624 }
2625 prompt_str = G.PS1;
2626 } 2592 }
2593# endif
2627 debug_printf("prompt_str '%s'\n", prompt_str); 2594 debug_printf("prompt_str '%s'\n", prompt_str);
2628 return prompt_str; 2595 return prompt_str;
2629} 2596}
@@ -7904,11 +7871,6 @@ static void remove_nested_vars(void)
7904 *cur_pp = cur->next; 7871 *cur_pp = cur->next;
7905 /* Free */ 7872 /* Free */
7906 if (!cur->max_len) { 7873 if (!cur->max_len) {
7907 /* Testcase (interactive):
7908 * f() { local PS1='\w \$ '; }; f
7909 * we should forget local PS1:
7910 */
7911 handle_changed_special_names(cur->varstr, endofname(cur->varstr) - cur->varstr);
7912 debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); 7874 debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7913 free(cur->varstr); 7875 free(cur->varstr);
7914 } 7876 }
@@ -9997,8 +9959,6 @@ int hush_main(int argc, char **argv)
9997#endif 9959#endif
9998 9960
9999 /* Initialize some more globals to non-zero values */ 9961 /* Initialize some more globals to non-zero values */
10000 cmdedit_update_prompt();
10001
10002 die_func = restore_ttypgrp_and__exit; 9962 die_func = restore_ttypgrp_and__exit;
10003 9963
10004 /* Shell is non-interactive at first. We need to call 9964 /* Shell is non-interactive at first. We need to call