hush: fix "wait -n" to wait for a _job_, not a _process_
function old new delta checkjobs 163 183 +20 process_wait_result 449 463 +14 leave_var_nest_level 98 107 +9 enter_var_nest_level 32 38 +6 set_vars_and_save_old 147 150 +3 builtin_local 53 56 +3 builtin_wait 322 323 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 7/0 up/down: 56/0) Total: 56 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
966f087ab4
commit
e6f51ac697
31
shell/hush.c
31
shell/hush.c
@ -923,7 +923,7 @@ struct globals {
|
|||||||
# define G_flag_return_in_progress 0
|
# define G_flag_return_in_progress 0
|
||||||
#endif
|
#endif
|
||||||
smallint exiting; /* used to prevent EXIT trap recursion */
|
smallint exiting; /* used to prevent EXIT trap recursion */
|
||||||
/* These support $?, $#, and $1 */
|
/* These support $? */
|
||||||
smalluint last_exitcode;
|
smalluint last_exitcode;
|
||||||
smalluint expand_exitcode;
|
smalluint expand_exitcode;
|
||||||
smalluint last_bg_pid_exitcode;
|
smalluint last_bg_pid_exitcode;
|
||||||
@ -933,6 +933,9 @@ struct globals {
|
|||||||
# define G_global_args_malloced (G.global_args_malloced)
|
# define G_global_args_malloced (G.global_args_malloced)
|
||||||
#else
|
#else
|
||||||
# define G_global_args_malloced 0
|
# define G_global_args_malloced 0
|
||||||
|
#endif
|
||||||
|
#if ENABLE_HUSH_BASH_COMPAT
|
||||||
|
int dead_job_exitcode; /* for "wait -n" */
|
||||||
#endif
|
#endif
|
||||||
/* how many non-NULL argv's we have. NB: $# + 1 */
|
/* how many non-NULL argv's we have. NB: $# + 1 */
|
||||||
int global_argc;
|
int global_argc;
|
||||||
@ -8657,6 +8660,9 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
|
|||||||
pi->cmds[i].pid = 0;
|
pi->cmds[i].pid = 0;
|
||||||
pi->alive_cmds--;
|
pi->alive_cmds--;
|
||||||
if (!pi->alive_cmds) {
|
if (!pi->alive_cmds) {
|
||||||
|
#if ENABLE_HUSH_BASH_COMPAT
|
||||||
|
G.dead_job_exitcode = job_exited_or_stopped(pi);
|
||||||
|
#endif
|
||||||
if (G_interactive_fd) {
|
if (G_interactive_fd) {
|
||||||
printf(JOB_STATUS_FORMAT, pi->jobid,
|
printf(JOB_STATUS_FORMAT, pi->jobid,
|
||||||
"Done", pi->cmdtext);
|
"Done", pi->cmdtext);
|
||||||
@ -8763,11 +8769,7 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
|
|||||||
/* fg_pipe exited or stopped */
|
/* fg_pipe exited or stopped */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (childpid == waitfor_pid /* "wait PID" */
|
if (childpid == waitfor_pid) { /* "wait PID" */
|
||||||
#if ENABLE_HUSH_BASH_COMPAT
|
|
||||||
|| -1 == waitfor_pid /* "wait -n" (wait for any one child) */
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
|
debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
|
||||||
rcode = WEXITSTATUS(status);
|
rcode = WEXITSTATUS(status);
|
||||||
if (WIFSIGNALED(status))
|
if (WIFSIGNALED(status))
|
||||||
@ -8778,6 +8780,15 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
|
|||||||
rcode++;
|
rcode++;
|
||||||
break; /* "wait PID" called us, give it exitcode+1 */
|
break; /* "wait PID" called us, give it exitcode+1 */
|
||||||
}
|
}
|
||||||
|
#if ENABLE_HUSH_BASH_COMPAT
|
||||||
|
if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */
|
||||||
|
&& G.dead_job_exitcode >= 0 /* some job did finish */
|
||||||
|
) {
|
||||||
|
debug_printf_exec("waitfor_pid:-1\n");
|
||||||
|
rcode = G.dead_job_exitcode + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* This wasn't one of our processes, or */
|
/* This wasn't one of our processes, or */
|
||||||
/* fg_pipe still has running processes, do waitpid again */
|
/* fg_pipe still has running processes, do waitpid again */
|
||||||
} /* while (waitpid succeeds)... */
|
} /* while (waitpid succeeds)... */
|
||||||
@ -11510,9 +11521,11 @@ static int FAST_FUNC builtin_wait(char **argv)
|
|||||||
|
|
||||||
argv = skip_dash_dash(argv);
|
argv = skip_dash_dash(argv);
|
||||||
#if ENABLE_HUSH_BASH_COMPAT
|
#if ENABLE_HUSH_BASH_COMPAT
|
||||||
if (argv[0] && !argv[1] && strcmp(argv[0], "-n") == 0) {
|
if (argv[0] && strcmp(argv[0], "-n") == 0) {
|
||||||
/* wait -n */
|
/* wait -n */
|
||||||
return wait_for_child_or_signal(NULL, -1 /*(no job, wait for one child)*/);
|
/* (bash accepts "wait -n PID" too and ignores PID) */
|
||||||
|
G.dead_job_exitcode = -1;
|
||||||
|
return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (argv[0] == NULL) {
|
if (argv[0] == NULL) {
|
||||||
@ -11532,7 +11545,7 @@ static int FAST_FUNC builtin_wait(char **argv)
|
|||||||
* ^C <-- after ~4 sec from keyboard
|
* ^C <-- after ~4 sec from keyboard
|
||||||
* $
|
* $
|
||||||
*/
|
*/
|
||||||
return wait_for_child_or_signal(NULL, 0 /*(no job and no pid to wait for)*/);
|
return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
Loading…
Reference in New Issue
Block a user