aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-17 14:35:43 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-17 14:35:43 +0000
commit4ea187fd62c57799784b06f3c37b63b7e3f6794a (patch)
treefb65fd6af09cb041edc2262d1f4f94d2b888549b /shell
parente4bd4f2cc8413bf3417ae902fcd14580a056a69c (diff)
downloadbusybox-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.c37
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) */
2869static void pseudo_exec_argv(nommu_save_t *nommu_save, 2869static 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);