mirror of
https://github.com/sheumann/hush.git
synced 2025-01-04 22:34:37 +00:00
hush: fix non-interactive response to pipe being stopped.
function old new delta checkjobs 380 394 +14
This commit is contained in:
parent
e4bd4f2cc8
commit
4ea187fd62
31
shell/hush.c
31
shell/hush.c
@ -2863,7 +2863,7 @@ static int run_function(const struct function *funcp, char **argv)
|
|||||||
|
|
||||||
/* Called after [v]fork() in run_pipe, or from builtin_exec.
|
/* Called after [v]fork() in run_pipe, or from builtin_exec.
|
||||||
* Never returns.
|
* Never returns.
|
||||||
* XXX no exit() here. If you don't exec, use _exit instead.
|
* Don't exit() here. If you don't exec, use _exit instead.
|
||||||
* The at_exit handlers apparently confuse the calling process,
|
* The at_exit handlers apparently confuse the calling process,
|
||||||
* in particular stdin handling. Not sure why? -- because of vfork! (vda) */
|
* in particular stdin handling. Not sure why? -- because of vfork! (vda) */
|
||||||
static void pseudo_exec_argv(nommu_save_t *nommu_save,
|
static void pseudo_exec_argv(nommu_save_t *nommu_save,
|
||||||
@ -3136,12 +3136,8 @@ static int checkjobs(struct pipe* fg_pipe)
|
|||||||
* [3]+ Stopped sleep 20 | false
|
* [3]+ Stopped sleep 20 | false
|
||||||
* bash-3.00# echo $?
|
* bash-3.00# echo $?
|
||||||
* 1 <========== bg pipe is not fully done, but exitcode is already known!
|
* 1 <========== bg pipe is not fully done, but exitcode is already known!
|
||||||
|
* [hush 1.14.0: yes we do it right]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//FIXME: non-interactive bash does not continue even if all processes in fg pipe
|
|
||||||
//are stopped. Testcase: "cat | cat" in a script (not on command line)
|
|
||||||
// + killall -STOP cat
|
|
||||||
|
|
||||||
wait_more:
|
wait_more:
|
||||||
while (1) {
|
while (1) {
|
||||||
int i;
|
int i;
|
||||||
@ -3175,7 +3171,6 @@ static int checkjobs(struct pipe* fg_pipe)
|
|||||||
debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
|
debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
|
||||||
if (fg_pipe->cmds[i].pid != childpid)
|
if (fg_pipe->cmds[i].pid != childpid)
|
||||||
continue;
|
continue;
|
||||||
/* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */
|
|
||||||
if (dead) {
|
if (dead) {
|
||||||
fg_pipe->cmds[i].pid = 0;
|
fg_pipe->cmds[i].pid = 0;
|
||||||
fg_pipe->alive_cmds--;
|
fg_pipe->alive_cmds--;
|
||||||
@ -3191,13 +3186,18 @@ static int checkjobs(struct pipe* fg_pipe)
|
|||||||
debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
|
debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
|
||||||
fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
|
fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
|
||||||
if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) {
|
if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) {
|
||||||
/* All processes in fg pipe have exited/stopped */
|
/* All processes in fg pipe have exited or stopped */
|
||||||
|
/* Note: *non-interactive* bash does not continue if all processes in fg pipe
|
||||||
|
* are stopped. Testcase: "cat | cat" in a script (not on command line!)
|
||||||
|
* and "killall -STOP cat" */
|
||||||
|
if (G_interactive_fd) {
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
if (fg_pipe->alive_cmds)
|
if (fg_pipe->alive_cmds)
|
||||||
insert_bg_job(fg_pipe);
|
insert_bg_job(fg_pipe);
|
||||||
#endif
|
#endif
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* There are still running processes in the fg pipe */
|
/* There are still running processes in the fg pipe */
|
||||||
goto wait_more; /* do waitpid again */
|
goto wait_more; /* do waitpid again */
|
||||||
}
|
}
|
||||||
@ -3400,10 +3400,10 @@ static int run_pipe(struct pipe *pi)
|
|||||||
goto clean_up_and_ret1;
|
goto clean_up_and_ret1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* XXX setup_redirects acts on file descriptors, not FILEs.
|
/* setup_redirects acts on file descriptors, not FILEs.
|
||||||
* This is perfect for work that comes after exec().
|
* This is perfect for work that comes after exec().
|
||||||
* Is it really safe for inline use? Experimentally,
|
* Is it really safe for inline use? Experimentally,
|
||||||
* things seem to work with glibc. */
|
* things seem to work. */
|
||||||
rcode = setup_redirects(command, squirrel);
|
rcode = setup_redirects(command, squirrel);
|
||||||
if (rcode == 0) {
|
if (rcode == 0) {
|
||||||
new_env = expand_assignments(argv, command->assignment_cnt);
|
new_env = expand_assignments(argv, command->assignment_cnt);
|
||||||
@ -5026,7 +5026,7 @@ static int handle_dollar(o_string *as_string,
|
|||||||
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||||
ch = i_getch(input);
|
ch = i_getch(input);
|
||||||
nommu_addchr(as_string, ch);
|
nommu_addchr(as_string, ch);
|
||||||
/* XXX maybe someone will try to escape the '}' */
|
/* TODO: maybe someone will try to escape the '}' */
|
||||||
expansion = 0;
|
expansion = 0;
|
||||||
first_char = true;
|
first_char = true;
|
||||||
all_digits = false;
|
all_digits = false;
|
||||||
@ -5992,7 +5992,7 @@ int hush_main(int argc, char **argv)
|
|||||||
/* If we are login shell... */
|
/* If we are login shell... */
|
||||||
if (argv[0] && argv[0][0] == '-') {
|
if (argv[0] && argv[0][0] == '-') {
|
||||||
FILE *input;
|
FILE *input;
|
||||||
/* XXX what should argv be while sourcing /etc/profile? */
|
/* TODO: what should argv be while sourcing /etc/profile? */
|
||||||
debug_printf("sourcing /etc/profile\n");
|
debug_printf("sourcing /etc/profile\n");
|
||||||
input = fopen_for_read("/etc/profile");
|
input = fopen_for_read("/etc/profile");
|
||||||
if (input != NULL) {
|
if (input != NULL) {
|
||||||
@ -6310,7 +6310,7 @@ static int builtin_exec(char **argv)
|
|||||||
#if !BB_MMU
|
#if !BB_MMU
|
||||||
nommu_save_t dummy;
|
nommu_save_t dummy;
|
||||||
#endif
|
#endif
|
||||||
// FIXME: if exec fails, bash does NOT exit! We do...
|
// TODO: if exec fails, bash does NOT exit! We do...
|
||||||
pseudo_exec_argv(&dummy, argv, 0, NULL);
|
pseudo_exec_argv(&dummy, argv, 0, NULL);
|
||||||
/* never returns */
|
/* never returns */
|
||||||
}
|
}
|
||||||
@ -6663,7 +6663,7 @@ static int builtin_source(char **argv)
|
|||||||
if (*++argv == NULL)
|
if (*++argv == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
/* XXX search through $PATH is missing */
|
/* TODO: search through $PATH is missing */
|
||||||
input = fopen_or_warn(*argv, "r");
|
input = fopen_or_warn(*argv, "r");
|
||||||
if (!input) {
|
if (!input) {
|
||||||
/* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
|
/* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
|
||||||
@ -6672,8 +6672,7 @@ static int builtin_source(char **argv)
|
|||||||
close_on_exec_on(fileno(input));
|
close_on_exec_on(fileno(input));
|
||||||
|
|
||||||
/* Now run the file */
|
/* Now run the file */
|
||||||
//TODO:
|
/* TODO: argv and argc are broken; need to save old G.global_argv
|
||||||
/* XXX argv and argc are broken; need to save old G.global_argv
|
|
||||||
* (pointer only is OK!) on this stack frame,
|
* (pointer only is OK!) on this stack frame,
|
||||||
* set G.global_argv=argv+1, recurse, and restore. */
|
* set G.global_argv=argv+1, recurse, and restore. */
|
||||||
parse_and_run_file(input);
|
parse_and_run_file(input);
|
||||||
|
Loading…
Reference in New Issue
Block a user