diff options
-rw-r--r-- | shell/hush.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/shell/hush.c b/shell/hush.c index 7c907686e..fa9afa38e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -923,7 +923,7 @@ struct globals { | |||
923 | # define G_flag_return_in_progress 0 | 923 | # define G_flag_return_in_progress 0 |
924 | #endif | 924 | #endif |
925 | smallint exiting; /* used to prevent EXIT trap recursion */ | 925 | smallint exiting; /* used to prevent EXIT trap recursion */ |
926 | /* These support $?, $#, and $1 */ | 926 | /* These support $? */ |
927 | smalluint last_exitcode; | 927 | smalluint last_exitcode; |
928 | smalluint expand_exitcode; | 928 | smalluint expand_exitcode; |
929 | smalluint last_bg_pid_exitcode; | 929 | smalluint last_bg_pid_exitcode; |
@@ -934,6 +934,9 @@ struct globals { | |||
934 | #else | 934 | #else |
935 | # define G_global_args_malloced 0 | 935 | # define G_global_args_malloced 0 |
936 | #endif | 936 | #endif |
937 | #if ENABLE_HUSH_BASH_COMPAT | ||
938 | int dead_job_exitcode; /* for "wait -n" */ | ||
939 | #endif | ||
937 | /* how many non-NULL argv's we have. NB: $# + 1 */ | 940 | /* how many non-NULL argv's we have. NB: $# + 1 */ |
938 | int global_argc; | 941 | int global_argc; |
939 | char **global_argv; | 942 | char **global_argv; |
@@ -8657,6 +8660,9 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) | |||
8657 | pi->cmds[i].pid = 0; | 8660 | pi->cmds[i].pid = 0; |
8658 | pi->alive_cmds--; | 8661 | pi->alive_cmds--; |
8659 | if (!pi->alive_cmds) { | 8662 | if (!pi->alive_cmds) { |
8663 | #if ENABLE_HUSH_BASH_COMPAT | ||
8664 | G.dead_job_exitcode = job_exited_or_stopped(pi); | ||
8665 | #endif | ||
8660 | if (G_interactive_fd) { | 8666 | if (G_interactive_fd) { |
8661 | printf(JOB_STATUS_FORMAT, pi->jobid, | 8667 | printf(JOB_STATUS_FORMAT, pi->jobid, |
8662 | "Done", pi->cmdtext); | 8668 | "Done", pi->cmdtext); |
@@ -8763,11 +8769,7 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) | |||
8763 | /* fg_pipe exited or stopped */ | 8769 | /* fg_pipe exited or stopped */ |
8764 | break; | 8770 | break; |
8765 | } | 8771 | } |
8766 | if (childpid == waitfor_pid /* "wait PID" */ | 8772 | if (childpid == waitfor_pid) { /* "wait PID" */ |
8767 | #if ENABLE_HUSH_BASH_COMPAT | ||
8768 | || -1 == waitfor_pid /* "wait -n" (wait for any one child) */ | ||
8769 | #endif | ||
8770 | ) { | ||
8771 | debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); | 8773 | debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); |
8772 | rcode = WEXITSTATUS(status); | 8774 | rcode = WEXITSTATUS(status); |
8773 | if (WIFSIGNALED(status)) | 8775 | if (WIFSIGNALED(status)) |
@@ -8778,6 +8780,15 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) | |||
8778 | rcode++; | 8780 | rcode++; |
8779 | break; /* "wait PID" called us, give it exitcode+1 */ | 8781 | break; /* "wait PID" called us, give it exitcode+1 */ |
8780 | } | 8782 | } |
8783 | #if ENABLE_HUSH_BASH_COMPAT | ||
8784 | if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */ | ||
8785 | && G.dead_job_exitcode >= 0 /* some job did finish */ | ||
8786 | ) { | ||
8787 | debug_printf_exec("waitfor_pid:-1\n"); | ||
8788 | rcode = G.dead_job_exitcode + 1; | ||
8789 | break; | ||
8790 | } | ||
8791 | #endif | ||
8781 | /* This wasn't one of our processes, or */ | 8792 | /* This wasn't one of our processes, or */ |
8782 | /* fg_pipe still has running processes, do waitpid again */ | 8793 | /* fg_pipe still has running processes, do waitpid again */ |
8783 | } /* while (waitpid succeeds)... */ | 8794 | } /* while (waitpid succeeds)... */ |
@@ -11510,9 +11521,11 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
11510 | 11521 | ||
11511 | argv = skip_dash_dash(argv); | 11522 | argv = skip_dash_dash(argv); |
11512 | #if ENABLE_HUSH_BASH_COMPAT | 11523 | #if ENABLE_HUSH_BASH_COMPAT |
11513 | if (argv[0] && !argv[1] && strcmp(argv[0], "-n") == 0) { | 11524 | if (argv[0] && strcmp(argv[0], "-n") == 0) { |
11514 | /* wait -n */ | 11525 | /* wait -n */ |
11515 | return wait_for_child_or_signal(NULL, -1 /*(no job, wait for one child)*/); | 11526 | /* (bash accepts "wait -n PID" too and ignores PID) */ |
11527 | G.dead_job_exitcode = -1; | ||
11528 | return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/); | ||
11516 | } | 11529 | } |
11517 | #endif | 11530 | #endif |
11518 | if (argv[0] == NULL) { | 11531 | if (argv[0] == NULL) { |
@@ -11532,7 +11545,7 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
11532 | * ^C <-- after ~4 sec from keyboard | 11545 | * ^C <-- after ~4 sec from keyboard |
11533 | * $ | 11546 | * $ |
11534 | */ | 11547 | */ |
11535 | return wait_for_child_or_signal(NULL, 0 /*(no job and no pid to wait for)*/); | 11548 | return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/); |
11536 | } | 11549 | } |
11537 | 11550 | ||
11538 | do { | 11551 | do { |