hush: functions have priority over builtins (!)
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 31 Jul 2017 03:27:09 +0000 (05:27 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 31 Jul 2017 03:27:09 +0000 (05:27 +0200)
function                                             old     new   delta
pseudo_exec_argv                                     291     305     +14
run_pipe                                            1560    1555      -5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 14/-5)               Total: 9 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash_test/ash-misc/func_prio_over_builtins.right [new file with mode: 0644]
shell/ash_test/ash-misc/func_prio_over_builtins.tests [new file with mode: 0755]
shell/hush.c
shell/hush_test/hush-misc/func_prio_over_builtins.right [new file with mode: 0644]
shell/hush_test/hush-misc/func_prio_over_builtins.tests [new file with mode: 0755]

diff --git a/shell/ash_test/ash-misc/func_prio_over_builtins.right b/shell/ash_test/ash-misc/func_prio_over_builtins.right
new file mode 100644 (file)
index 0000000..54e56df
--- /dev/null
@@ -0,0 +1,5 @@
+YES
+YES
+YES
+YES
+Ok:YES
diff --git a/shell/ash_test/ash-misc/func_prio_over_builtins.tests b/shell/ash_test/ash-misc/func_prio_over_builtins.tests
new file mode 100755 (executable)
index 0000000..4f71bfd
--- /dev/null
@@ -0,0 +1,5 @@
+true() { echo YES >&2; }
+true
+true | true
+(true)
+echo Ok:`true 2>&1`
index 8e9e0e9e8a76304bc621a02e8d1658ab35c8d964..2fba637aed0e02b699ac4243bc10e667a25a290f 100644 (file)
@@ -7090,11 +7090,13 @@ static void exec_function(char ***to_free,
        argv[0] = G.global_argv[0];
        G.global_argv = argv;
        G.global_argc = n = 1 + string_array_len(argv + 1);
+//?    close_saved_fds_and_FILE_list();
        /* On MMU, funcp->body is always non-NULL */
        n = run_list(funcp->body);
        fflush_all();
        _exit(n);
 # else
+//?    close_saved_fds_and_FILE_list();
        re_execute_shell(to_free,
                        funcp->body_as_string,
                        G.global_argv[0],
@@ -7180,6 +7182,7 @@ static void exec_builtin(char ***to_free,
 #if BB_MMU
        int rcode;
        fflush_all();
+//?    close_saved_fds_and_FILE_list();
        rcode = x->b_function(argv);
        fflush_all();
        _exit(rcode);
@@ -7301,6 +7304,16 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
                goto skip;
 #endif
 
+#if ENABLE_HUSH_FUNCTIONS
+       /* Check if the command matches any functions (this goes before bltins) */
+       {
+               const struct function *funcp = find_function(argv[0]);
+               if (funcp) {
+                       exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
+               }
+       }
+#endif
+
        /* Check if the command matches any of the builtins.
         * Depending on context, this might be redundant.  But it's
         * easier to waste a few CPU cycles than it is to figure out
@@ -7317,15 +7330,6 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
                        exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
                }
        }
-#if ENABLE_HUSH_FUNCTIONS
-       /* Check if the command matches any functions */
-       {
-               const struct function *funcp = find_function(argv[0]);
-               if (funcp) {
-                       exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
-               }
-       }
-#endif
 
 #if ENABLE_FEATURE_SH_STANDALONE
        /* Check if the command matches any busybox applets */
@@ -7339,7 +7343,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
                                 * should not show tty fd open.
                                 */
                                close_saved_fds_and_FILE_list();
-///FIXME: should also close saved redir fds
+//FIXME: should also close saved redir fds
                                debug_printf_exec("running applet '%s'\n", argv[0]);
                                run_applet_no_and_exit(a, argv[0], argv);
                        }
@@ -7976,12 +7980,13 @@ static NOINLINE int run_pipe(struct pipe *pi)
                        return G.last_exitcode;
                }
 
-               x = find_builtin(argv_expanded[0]);
 #if ENABLE_HUSH_FUNCTIONS
-               funcp = NULL;
-               if (!x)
-                       funcp = find_function(argv_expanded[0]);
+               /* Check if argv[0] matches any functions (this goes before bltins) */
+               funcp = find_function(argv_expanded[0]);
 #endif
+               x = NULL;
+               if (!funcp)
+                       x = find_builtin(argv_expanded[0]);
                if (x || funcp) {
                        if (!funcp) {
                                if (x->b_function == builtin_exec && argv_expanded[1] == NULL) {
diff --git a/shell/hush_test/hush-misc/func_prio_over_builtins.right b/shell/hush_test/hush-misc/func_prio_over_builtins.right
new file mode 100644 (file)
index 0000000..54e56df
--- /dev/null
@@ -0,0 +1,5 @@
+YES
+YES
+YES
+YES
+Ok:YES
diff --git a/shell/hush_test/hush-misc/func_prio_over_builtins.tests b/shell/hush_test/hush-misc/func_prio_over_builtins.tests
new file mode 100755 (executable)
index 0000000..4f71bfd
--- /dev/null
@@ -0,0 +1,5 @@
+true() { echo YES >&2; }
+true
+true | true
+(true)
+echo Ok:`true 2>&1`