← Commit list

558ef4962

Denys Vlasenko
Denys Vlasenko
2025-08-07
SUCCESS Duration: 172s

Subject

hush: optimization: do not glob words "[" and "[["

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/hush.c+40 -0
@@ -115,6 +115,11 @@
//config:# It's only needed to get "nice" menuconfig indenting.
//config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH
//config:
+//config:config HUSH_NEED_FOR_SPEED
+//config: bool "Faster, but larger code"
+//config: default y
+//config: depends on SHELL_HUSH
+//config:
//config:config HUSH_BASH_COMPAT
//config: bool "bash-compatible extensions"
//config: default y
@@ -3381,6 +3386,24 @@ static int o_get_last_ptr(o_string *o, int n)
/* Helper */
static int glob_needed(const char *s)
{
+# if ENABLE_HUSH_NEED_FOR_SPEED
+ char c = *s;
+ if (c == '[' /*|| c == '{'*/) {
+ /* Special-case words consisting entirely of [.
+ * Optimization to avoid glob()
+ * on "[ COND ]" and "[[ COND ]]":
+ * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done'
+ * shouldn't be doing 50000 stat("[").
+ * (Can do it for "{" too, but it's not a common case).
+ */
+ const char *p = s;
+ while (*++p == c)
+ continue;
+ if (*p == '\0')
+ return 0;
+ }
+# endif
+
while (*s) {
if (*s == '\\') {
if (!s[1])
@@ -3572,6 +3595,23 @@ static int perform_glob(o_string *o, int n)
/* Helper */
static int glob_needed(const char *s)
{
+# if ENABLE_HUSH_NEED_FOR_SPEED
+ char c = *s;
+ if (c == '[') {
+ /* Special-case words consisting entirely of [.
+ * Optimization to avoid glob()
+ * on "[ COND ]" and "[[ COND ]]":
+ * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done'
+ * shouldn't be doing 50000 stat("[").
+ */
+ const char *p = s;
+ while (*++p == c)
+ continue;
+ if (*p == '\0')
+ return 0;
+ }
+# endif
+
while (*s) {
if (*s == '\\') {
if (!s[1])