diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-17 14:35:43 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-17 14:35:43 +0000 |
commit | 4ea187fd62c57799784b06f3c37b63b7e3f6794a (patch) | |
tree | fb65fd6af09cb041edc2262d1f4f94d2b888549b /shell | |
parent | e4bd4f2cc8413bf3417ae902fcd14580a056a69c (diff) | |
download | busybox-w32-4ea187fd62c57799784b06f3c37b63b7e3f6794a.tar.gz busybox-w32-4ea187fd62c57799784b06f3c37b63b7e3f6794a.tar.bz2 busybox-w32-4ea187fd62c57799784b06f3c37b63b7e3f6794a.zip |
hush: fix non-interactive response to pipe being stopped.
function old new delta
checkjobs 380 394 +14
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/shell/hush.c b/shell/hush.c index 13a06a492..4a0fc2353 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2863,7 +2863,7 @@ static int run_function(const struct function *funcp, char **argv) | |||
2863 | 2863 | ||
2864 | /* Called after [v]fork() in run_pipe, or from builtin_exec. | 2864 | /* Called after [v]fork() in run_pipe, or from builtin_exec. |
2865 | * Never returns. | 2865 | * Never returns. |
2866 | * XXX no exit() here. If you don't exec, use _exit instead. | 2866 | * Don't exit() here. If you don't exec, use _exit instead. |
2867 | * The at_exit handlers apparently confuse the calling process, | 2867 | * The at_exit handlers apparently confuse the calling process, |
2868 | * in particular stdin handling. Not sure why? -- because of vfork! (vda) */ | 2868 | * in particular stdin handling. Not sure why? -- because of vfork! (vda) */ |
2869 | static void pseudo_exec_argv(nommu_save_t *nommu_save, | 2869 | static void pseudo_exec_argv(nommu_save_t *nommu_save, |
@@ -3136,12 +3136,8 @@ static int checkjobs(struct pipe* fg_pipe) | |||
3136 | * [3]+ Stopped sleep 20 | false | 3136 | * [3]+ Stopped sleep 20 | false |
3137 | * bash-3.00# echo $? | 3137 | * bash-3.00# echo $? |
3138 | * 1 <========== bg pipe is not fully done, but exitcode is already known! | 3138 | * 1 <========== bg pipe is not fully done, but exitcode is already known! |
3139 | * [hush 1.14.0: yes we do it right] | ||
3139 | */ | 3140 | */ |
3140 | |||
3141 | //FIXME: non-interactive bash does not continue even if all processes in fg pipe | ||
3142 | //are stopped. Testcase: "cat | cat" in a script (not on command line) | ||
3143 | // + killall -STOP cat | ||
3144 | |||
3145 | wait_more: | 3141 | wait_more: |
3146 | while (1) { | 3142 | while (1) { |
3147 | int i; | 3143 | int i; |
@@ -3175,7 +3171,6 @@ static int checkjobs(struct pipe* fg_pipe) | |||
3175 | debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid); | 3171 | debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid); |
3176 | if (fg_pipe->cmds[i].pid != childpid) | 3172 | if (fg_pipe->cmds[i].pid != childpid) |
3177 | continue; | 3173 | continue; |
3178 | /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */ | ||
3179 | if (dead) { | 3174 | if (dead) { |
3180 | fg_pipe->cmds[i].pid = 0; | 3175 | fg_pipe->cmds[i].pid = 0; |
3181 | fg_pipe->alive_cmds--; | 3176 | fg_pipe->alive_cmds--; |
@@ -3191,12 +3186,17 @@ static int checkjobs(struct pipe* fg_pipe) | |||
3191 | debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n", | 3186 | debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n", |
3192 | fg_pipe->alive_cmds, fg_pipe->stopped_cmds); | 3187 | fg_pipe->alive_cmds, fg_pipe->stopped_cmds); |
3193 | if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) { | 3188 | if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) { |
3194 | /* All processes in fg pipe have exited/stopped */ | 3189 | /* All processes in fg pipe have exited or stopped */ |
3190 | /* Note: *non-interactive* bash does not continue if all processes in fg pipe | ||
3191 | * are stopped. Testcase: "cat | cat" in a script (not on command line!) | ||
3192 | * and "killall -STOP cat" */ | ||
3193 | if (G_interactive_fd) { | ||
3195 | #if ENABLE_HUSH_JOB | 3194 | #if ENABLE_HUSH_JOB |
3196 | if (fg_pipe->alive_cmds) | 3195 | if (fg_pipe->alive_cmds) |
3197 | insert_bg_job(fg_pipe); | 3196 | insert_bg_job(fg_pipe); |
3198 | #endif | 3197 | #endif |
3199 | return rcode; | 3198 | return rcode; |
3199 | } | ||
3200 | } | 3200 | } |
3201 | /* There are still running processes in the fg pipe */ | 3201 | /* There are still running processes in the fg pipe */ |
3202 | goto wait_more; /* do waitpid again */ | 3202 | goto wait_more; /* do waitpid again */ |
@@ -3400,10 +3400,10 @@ static int run_pipe(struct pipe *pi) | |||
3400 | goto clean_up_and_ret1; | 3400 | goto clean_up_and_ret1; |
3401 | } | 3401 | } |
3402 | } | 3402 | } |
3403 | /* XXX setup_redirects acts on file descriptors, not FILEs. | 3403 | /* setup_redirects acts on file descriptors, not FILEs. |
3404 | * This is perfect for work that comes after exec(). | 3404 | * This is perfect for work that comes after exec(). |
3405 | * Is it really safe for inline use? Experimentally, | 3405 | * Is it really safe for inline use? Experimentally, |
3406 | * things seem to work with glibc. */ | 3406 | * things seem to work. */ |
3407 | rcode = setup_redirects(command, squirrel); | 3407 | rcode = setup_redirects(command, squirrel); |
3408 | if (rcode == 0) { | 3408 | if (rcode == 0) { |
3409 | new_env = expand_assignments(argv, command->assignment_cnt); | 3409 | new_env = expand_assignments(argv, command->assignment_cnt); |
@@ -5026,7 +5026,7 @@ static int handle_dollar(o_string *as_string, | |||
5026 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 5026 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
5027 | ch = i_getch(input); | 5027 | ch = i_getch(input); |
5028 | nommu_addchr(as_string, ch); | 5028 | nommu_addchr(as_string, ch); |
5029 | /* XXX maybe someone will try to escape the '}' */ | 5029 | /* TODO: maybe someone will try to escape the '}' */ |
5030 | expansion = 0; | 5030 | expansion = 0; |
5031 | first_char = true; | 5031 | first_char = true; |
5032 | all_digits = false; | 5032 | all_digits = false; |
@@ -5992,7 +5992,7 @@ int hush_main(int argc, char **argv) | |||
5992 | /* If we are login shell... */ | 5992 | /* If we are login shell... */ |
5993 | if (argv[0] && argv[0][0] == '-') { | 5993 | if (argv[0] && argv[0][0] == '-') { |
5994 | FILE *input; | 5994 | FILE *input; |
5995 | /* XXX what should argv be while sourcing /etc/profile? */ | 5995 | /* TODO: what should argv be while sourcing /etc/profile? */ |
5996 | debug_printf("sourcing /etc/profile\n"); | 5996 | debug_printf("sourcing /etc/profile\n"); |
5997 | input = fopen_for_read("/etc/profile"); | 5997 | input = fopen_for_read("/etc/profile"); |
5998 | if (input != NULL) { | 5998 | if (input != NULL) { |
@@ -6310,7 +6310,7 @@ static int builtin_exec(char **argv) | |||
6310 | #if !BB_MMU | 6310 | #if !BB_MMU |
6311 | nommu_save_t dummy; | 6311 | nommu_save_t dummy; |
6312 | #endif | 6312 | #endif |
6313 | // FIXME: if exec fails, bash does NOT exit! We do... | 6313 | // TODO: if exec fails, bash does NOT exit! We do... |
6314 | pseudo_exec_argv(&dummy, argv, 0, NULL); | 6314 | pseudo_exec_argv(&dummy, argv, 0, NULL); |
6315 | /* never returns */ | 6315 | /* never returns */ |
6316 | } | 6316 | } |
@@ -6663,7 +6663,7 @@ static int builtin_source(char **argv) | |||
6663 | if (*++argv == NULL) | 6663 | if (*++argv == NULL) |
6664 | return EXIT_FAILURE; | 6664 | return EXIT_FAILURE; |
6665 | 6665 | ||
6666 | /* XXX search through $PATH is missing */ | 6666 | /* TODO: search through $PATH is missing */ |
6667 | input = fopen_or_warn(*argv, "r"); | 6667 | input = fopen_or_warn(*argv, "r"); |
6668 | if (!input) { | 6668 | if (!input) { |
6669 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ | 6669 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ |
@@ -6672,8 +6672,7 @@ static int builtin_source(char **argv) | |||
6672 | close_on_exec_on(fileno(input)); | 6672 | close_on_exec_on(fileno(input)); |
6673 | 6673 | ||
6674 | /* Now run the file */ | 6674 | /* Now run the file */ |
6675 | //TODO: | 6675 | /* TODO: argv and argc are broken; need to save old G.global_argv |
6676 | /* XXX argv and argc are broken; need to save old G.global_argv | ||
6677 | * (pointer only is OK!) on this stack frame, | 6676 | * (pointer only is OK!) on this stack frame, |
6678 | * set G.global_argv=argv+1, recurse, and restore. */ | 6677 | * set G.global_argv=argv+1, recurse, and restore. */ |
6679 | parse_and_run_file(input); | 6678 | parse_and_run_file(input); |