aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-07 00:00:03 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-07 00:20:56 +0200
commit558ef4962dd3adb9e63b4c0787f8d4902fc909d4 (patch)
tree58471921ed2175dabe0e3753217593960867c12e /shell
parent8f5d890071932cb472db439d1f81cc298a25583a (diff)
downloadbusybox-w32-558ef4962dd3adb9e63b4c0787f8d4902fc909d4.tar.gz
busybox-w32-558ef4962dd3adb9e63b4c0787f8d4902fc909d4.tar.bz2
busybox-w32-558ef4962dd3adb9e63b4c0787f8d4902fc909d4.zip
hush: optimization: do not glob words "[" and "[["
function old new delta glob_needed 71 86 +15 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 09ab6ebc0..6129a087b 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -115,6 +115,11 @@
115//config:# It's only needed to get "nice" menuconfig indenting. 115//config:# It's only needed to get "nice" menuconfig indenting.
116//config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH 116//config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH
117//config: 117//config:
118//config:config HUSH_NEED_FOR_SPEED
119//config: bool "Faster, but larger code"
120//config: default y
121//config: depends on SHELL_HUSH
122//config:
118//config:config HUSH_BASH_COMPAT 123//config:config HUSH_BASH_COMPAT
119//config: bool "bash-compatible extensions" 124//config: bool "bash-compatible extensions"
120//config: default y 125//config: default y
@@ -3381,6 +3386,24 @@ static int o_get_last_ptr(o_string *o, int n)
3381/* Helper */ 3386/* Helper */
3382static int glob_needed(const char *s) 3387static int glob_needed(const char *s)
3383{ 3388{
3389# if ENABLE_HUSH_NEED_FOR_SPEED
3390 char c = *s;
3391 if (c == '[' /*|| c == '{'*/) {
3392 /* Special-case words consisting entirely of [.
3393 * Optimization to avoid glob()
3394 * on "[ COND ]" and "[[ COND ]]":
3395 * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done'
3396 * shouldn't be doing 50000 stat("[").
3397 * (Can do it for "{" too, but it's not a common case).
3398 */
3399 const char *p = s;
3400 while (*++p == c)
3401 continue;
3402 if (*p == '\0')
3403 return 0;
3404 }
3405# endif
3406
3384 while (*s) { 3407 while (*s) {
3385 if (*s == '\\') { 3408 if (*s == '\\') {
3386 if (!s[1]) 3409 if (!s[1])
@@ -3572,6 +3595,23 @@ static int perform_glob(o_string *o, int n)
3572/* Helper */ 3595/* Helper */
3573static int glob_needed(const char *s) 3596static int glob_needed(const char *s)
3574{ 3597{
3598# if ENABLE_HUSH_NEED_FOR_SPEED
3599 char c = *s;
3600 if (c == '[') {
3601 /* Special-case words consisting entirely of [.
3602 * Optimization to avoid glob()
3603 * on "[ COND ]" and "[[ COND ]]":
3604 * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done'
3605 * shouldn't be doing 50000 stat("[").
3606 */
3607 const char *p = s;
3608 while (*++p == c)
3609 continue;
3610 if (*p == '\0')
3611 return 0;
3612 }
3613# endif
3614
3575 while (*s) { 3615 while (*s) {
3576 if (*s == '\\') { 3616 if (*s == '\\') {
3577 if (!s[1]) 3617 if (!s[1])