diff options
-rw-r--r-- | shell/ash_test/ash-misc/func_return1.right (renamed from shell/ash_test/ash-misc/func6.right) | 0 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_return1.tests (renamed from shell/ash_test/ash-misc/func6.tests) | 0 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func_return2.right (renamed from shell/hush_test/hush-misc/func6.right) | 0 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func_return2.tests | 6 | ||||
-rw-r--r-- | shell/hush.c | 44 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/func_return1.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/func_return1.tests (renamed from shell/hush_test/hush-misc/func6.tests) | 0 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/func_return2.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/func_return2.tests | 6 |
9 files changed, 52 insertions, 8 deletions
diff --git a/shell/ash_test/ash-misc/func6.right b/shell/ash_test/ash-misc/func_return1.right index 0ebd8e5a3..0ebd8e5a3 100644 --- a/shell/ash_test/ash-misc/func6.right +++ b/shell/ash_test/ash-misc/func_return1.right | |||
diff --git a/shell/ash_test/ash-misc/func6.tests b/shell/ash_test/ash-misc/func_return1.tests index 029c3e85e..029c3e85e 100755 --- a/shell/ash_test/ash-misc/func6.tests +++ b/shell/ash_test/ash-misc/func_return1.tests | |||
diff --git a/shell/hush_test/hush-misc/func6.right b/shell/ash_test/ash-misc/func_return2.right index 0ebd8e5a3..0ebd8e5a3 100644 --- a/shell/hush_test/hush-misc/func6.right +++ b/shell/ash_test/ash-misc/func_return2.right | |||
diff --git a/shell/ash_test/ash-misc/func_return2.tests b/shell/ash_test/ash-misc/func_return2.tests new file mode 100755 index 000000000..a049dd180 --- /dev/null +++ b/shell/ash_test/ash-misc/func_return2.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | f1() { return 2; } | ||
2 | f1 | ||
3 | echo Two:$? | ||
4 | false | ||
5 | true | f1 | ||
6 | echo Two:$? | ||
diff --git a/shell/hush.c b/shell/hush.c index 2fba637ae..5c8e00743 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -6804,7 +6804,7 @@ static void restore_redirects(struct squirrel *sq) | |||
6804 | } | 6804 | } |
6805 | 6805 | ||
6806 | #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU | 6806 | #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU |
6807 | static void close_saved_fds_and_FILE_list(void) | 6807 | static void close_saved_fds_and_FILE_fds(void) |
6808 | { | 6808 | { |
6809 | if (G_interactive_fd) | 6809 | if (G_interactive_fd) |
6810 | close(G_interactive_fd); | 6810 | close(G_interactive_fd); |
@@ -7090,13 +7090,35 @@ static void exec_function(char ***to_free, | |||
7090 | argv[0] = G.global_argv[0]; | 7090 | argv[0] = G.global_argv[0]; |
7091 | G.global_argv = argv; | 7091 | G.global_argv = argv; |
7092 | G.global_argc = n = 1 + string_array_len(argv + 1); | 7092 | G.global_argc = n = 1 + string_array_len(argv + 1); |
7093 | //? close_saved_fds_and_FILE_list(); | 7093 | |
7094 | // Example when we are here: "cmd | func" | ||
7095 | // func will run with saved-redirect fds open. | ||
7096 | // $ f() { echo /proc/self/fd/*; } | ||
7097 | // $ true | f | ||
7098 | // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 | ||
7099 | // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob | ||
7100 | // Same in script: | ||
7101 | // $ . ./SCRIPT | ||
7102 | // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4 | ||
7103 | // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob | ||
7104 | // They are CLOEXEC so external programs won't see them, but | ||
7105 | // for "more correctness" we might want to close those extra fds here: | ||
7106 | //? close_saved_fds_and_FILE_fds(); | ||
7107 | |||
7108 | /* "we are in function, ok to use return" */ | ||
7109 | G_flag_return_in_progress = -1; | ||
7110 | IF_HUSH_LOCAL(G.func_nest_level++;) | ||
7111 | |||
7112 | G_flag_return_in_progress = -1; | ||
7094 | /* On MMU, funcp->body is always non-NULL */ | 7113 | /* On MMU, funcp->body is always non-NULL */ |
7095 | n = run_list(funcp->body); | 7114 | n = run_list(funcp->body); |
7096 | fflush_all(); | 7115 | fflush_all(); |
7097 | _exit(n); | 7116 | _exit(n); |
7098 | # else | 7117 | # else |
7099 | //? close_saved_fds_and_FILE_list(); | 7118 | //? close_saved_fds_and_FILE_fds(); |
7119 | |||
7120 | //TODO: check whether "true | func_with_return" works | ||
7121 | |||
7100 | re_execute_shell(to_free, | 7122 | re_execute_shell(to_free, |
7101 | funcp->body_as_string, | 7123 | funcp->body_as_string, |
7102 | G.global_argv[0], | 7124 | G.global_argv[0], |
@@ -7116,9 +7138,7 @@ static int run_function(const struct function *funcp, char **argv) | |||
7116 | /* "we are in function, ok to use return" */ | 7138 | /* "we are in function, ok to use return" */ |
7117 | sv_flg = G_flag_return_in_progress; | 7139 | sv_flg = G_flag_return_in_progress; |
7118 | G_flag_return_in_progress = -1; | 7140 | G_flag_return_in_progress = -1; |
7119 | # if ENABLE_HUSH_LOCAL | 7141 | IF_HUSH_LOCAL(G.func_nest_level++;) |
7120 | G.func_nest_level++; | ||
7121 | # endif | ||
7122 | 7142 | ||
7123 | /* On MMU, funcp->body is always non-NULL */ | 7143 | /* On MMU, funcp->body is always non-NULL */ |
7124 | # if !BB_MMU | 7144 | # if !BB_MMU |
@@ -7182,7 +7202,7 @@ static void exec_builtin(char ***to_free, | |||
7182 | #if BB_MMU | 7202 | #if BB_MMU |
7183 | int rcode; | 7203 | int rcode; |
7184 | fflush_all(); | 7204 | fflush_all(); |
7185 | //? close_saved_fds_and_FILE_list(); | 7205 | //? close_saved_fds_and_FILE_fds(); |
7186 | rcode = x->b_function(argv); | 7206 | rcode = x->b_function(argv); |
7187 | fflush_all(); | 7207 | fflush_all(); |
7188 | _exit(rcode); | 7208 | _exit(rcode); |
@@ -7342,7 +7362,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
7342 | * Testcase: interactive "ls -l /proc/self/fd" | 7362 | * Testcase: interactive "ls -l /proc/self/fd" |
7343 | * should not show tty fd open. | 7363 | * should not show tty fd open. |
7344 | */ | 7364 | */ |
7345 | close_saved_fds_and_FILE_list(); | 7365 | close_saved_fds_and_FILE_fds(); |
7346 | //FIXME: should also close saved redir fds | 7366 | //FIXME: should also close saved redir fds |
7347 | debug_printf_exec("running applet '%s'\n", argv[0]); | 7367 | debug_printf_exec("running applet '%s'\n", argv[0]); |
7348 | run_applet_no_and_exit(a, argv[0], argv); | 7368 | run_applet_no_and_exit(a, argv[0], argv); |
@@ -9253,6 +9273,14 @@ static int FAST_FUNC builtin_exec(char **argv) | |||
9253 | if (G_saved_tty_pgrp && getpid() == G.root_pid) | 9273 | if (G_saved_tty_pgrp && getpid() == G.root_pid) |
9254 | tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp); | 9274 | tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp); |
9255 | 9275 | ||
9276 | /* Saved-redirect fds, script fds and G_interactive_fd are still | ||
9277 | * open here. However, they are all CLOEXEC, and execv below | ||
9278 | * closes them. Try interactive "exec ls -l /proc/self/fd", | ||
9279 | * it should show no extra open fds in the "ls" process. | ||
9280 | * If we'd try to run builtins/NOEXECs, this would need improving. | ||
9281 | */ | ||
9282 | //close_saved_fds_and_FILE_fds(); | ||
9283 | |||
9256 | /* TODO: if exec fails, bash does NOT exit! We do. | 9284 | /* TODO: if exec fails, bash does NOT exit! We do. |
9257 | * We'll need to undo trap cleanup (it's inside execvp_or_die) | 9285 | * We'll need to undo trap cleanup (it's inside execvp_or_die) |
9258 | * and tcsetpgrp, and this is inherently racy. | 9286 | * and tcsetpgrp, and this is inherently racy. |
diff --git a/shell/hush_test/hush-misc/func_return1.right b/shell/hush_test/hush-misc/func_return1.right new file mode 100644 index 000000000..0ebd8e5a3 --- /dev/null +++ b/shell/hush_test/hush-misc/func_return1.right | |||
@@ -0,0 +1,2 @@ | |||
1 | Two:2 | ||
2 | Two:2 | ||
diff --git a/shell/hush_test/hush-misc/func6.tests b/shell/hush_test/hush-misc/func_return1.tests index 029c3e85e..029c3e85e 100755 --- a/shell/hush_test/hush-misc/func6.tests +++ b/shell/hush_test/hush-misc/func_return1.tests | |||
diff --git a/shell/hush_test/hush-misc/func_return2.right b/shell/hush_test/hush-misc/func_return2.right new file mode 100644 index 000000000..0ebd8e5a3 --- /dev/null +++ b/shell/hush_test/hush-misc/func_return2.right | |||
@@ -0,0 +1,2 @@ | |||
1 | Two:2 | ||
2 | Two:2 | ||
diff --git a/shell/hush_test/hush-misc/func_return2.tests b/shell/hush_test/hush-misc/func_return2.tests new file mode 100755 index 000000000..a049dd180 --- /dev/null +++ b/shell/hush_test/hush-misc/func_return2.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | f1() { return 2; } | ||
2 | f1 | ||
3 | echo Two:$? | ||
4 | false | ||
5 | true | f1 | ||
6 | echo Two:$? | ||