diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-07 22:56:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-07 22:56:02 +0200 |
commit | 840a4355d035efc360eeefe5da8a11e47b3c80d3 (patch) | |
tree | d68c5ee3d534e241f1585188699ab987c5e01fd2 /shell | |
parent | 2db74610cdf8ffb4f9ed99b62c755377d3cc48ea (diff) | |
download | busybox-w32-840a4355d035efc360eeefe5da8a11e47b3c80d3.tar.gz busybox-w32-840a4355d035efc360eeefe5da8a11e47b3c80d3.tar.bz2 busybox-w32-840a4355d035efc360eeefe5da8a11e47b3c80d3.zip |
hush: fix "(sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?"
function old new delta
process_wait_result 414 426 +12
builtin_wait 283 291 +8
run_list 974 978 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 24/0) Total: 24 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_test/ash-misc/wait6.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/wait6.tests | 6 | ||||
-rw-r--r-- | shell/hush.c | 15 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/wait6.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/wait6.tests | 6 |
5 files changed, 26 insertions, 5 deletions
diff --git a/shell/ash_test/ash-misc/wait6.right b/shell/ash_test/ash-misc/wait6.right new file mode 100644 index 000000000..12decc137 --- /dev/null +++ b/shell/ash_test/ash-misc/wait6.right | |||
@@ -0,0 +1,2 @@ | |||
1 | 0 | ||
2 | 3 | ||
diff --git a/shell/ash_test/ash-misc/wait6.tests b/shell/ash_test/ash-misc/wait6.tests new file mode 100755 index 000000000..c23713199 --- /dev/null +++ b/shell/ash_test/ash-misc/wait6.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | # In bash, "wait $!" extracts correct exitcode even if bg task has already exited | ||
2 | # It prints 0, then 3: | ||
3 | (sleep 0; exit 3) & sleep 1 | ||
4 | echo $? | ||
5 | wait $! | ||
6 | echo $? | ||
diff --git a/shell/hush.c b/shell/hush.c index 59bddbfff..df96e6fde 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -832,6 +832,7 @@ struct globals { | |||
832 | smallint exiting; /* used to prevent EXIT trap recursion */ | 832 | smallint exiting; /* used to prevent EXIT trap recursion */ |
833 | /* These four support $?, $#, and $1 */ | 833 | /* These four support $?, $#, and $1 */ |
834 | smalluint last_exitcode; | 834 | smalluint last_exitcode; |
835 | smalluint last_bg_pid_exitcode; | ||
835 | #if ENABLE_HUSH_SET | 836 | #if ENABLE_HUSH_SET |
836 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ | 837 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ |
837 | smalluint global_args_malloced; | 838 | smalluint global_args_malloced; |
@@ -7387,10 +7388,13 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) | |||
7387 | found_pi_and_prognum: | 7388 | found_pi_and_prognum: |
7388 | if (dead) { | 7389 | if (dead) { |
7389 | /* child exited */ | 7390 | /* child exited */ |
7390 | pi->cmds[i].pid = 0; | 7391 | int rcode = WEXITSTATUS(status); |
7391 | pi->cmds[i].cmd_exitcode = WEXITSTATUS(status); | ||
7392 | if (WIFSIGNALED(status)) | 7392 | if (WIFSIGNALED(status)) |
7393 | pi->cmds[i].cmd_exitcode = 128 + WTERMSIG(status); | 7393 | rcode = 128 + WTERMSIG(status); |
7394 | pi->cmds[i].cmd_exitcode = rcode; | ||
7395 | if (G.last_bg_pid == pi->cmds[i].pid) | ||
7396 | G.last_bg_pid_exitcode = rcode; | ||
7397 | pi->cmds[i].pid = 0; | ||
7394 | pi->alive_cmds--; | 7398 | pi->alive_cmds--; |
7395 | if (!pi->alive_cmds) { | 7399 | if (!pi->alive_cmds) { |
7396 | if (G_interactive_fd) | 7400 | if (G_interactive_fd) |
@@ -8215,6 +8219,7 @@ static int run_list(struct pipe *pi) | |||
8215 | #endif | 8219 | #endif |
8216 | /* Last command's pid goes to $! */ | 8220 | /* Last command's pid goes to $! */ |
8217 | G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid; | 8221 | G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid; |
8222 | G.last_bg_pid_exitcode = 0; | ||
8218 | debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); | 8223 | debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); |
8219 | /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash says 0 */ | 8224 | /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash says 0 */ |
8220 | rcode = EXIT_SUCCESS; | 8225 | rcode = EXIT_SUCCESS; |
@@ -9909,6 +9914,7 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9909 | ret = waitpid(pid, &status, WNOHANG); | 9914 | ret = waitpid(pid, &status, WNOHANG); |
9910 | if (ret < 0) { | 9915 | if (ret < 0) { |
9911 | /* No */ | 9916 | /* No */ |
9917 | ret = 127; | ||
9912 | if (errno == ECHILD) { | 9918 | if (errno == ECHILD) { |
9913 | if (G.last_bg_pid > 0 && pid == G.last_bg_pid) { | 9919 | if (G.last_bg_pid > 0 && pid == G.last_bg_pid) { |
9914 | /* "wait $!" but last bg task has already exited. Try: | 9920 | /* "wait $!" but last bg task has already exited. Try: |
@@ -9916,7 +9922,7 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9916 | * In bash it prints exitcode 0, then 3. | 9922 | * In bash it prints exitcode 0, then 3. |
9917 | * In dash, it is 127. | 9923 | * In dash, it is 127. |
9918 | */ | 9924 | */ |
9919 | /* ret = G.last_bg_pid_exitstatus - FIXME */ | 9925 | ret = G.last_bg_pid_exitcode; |
9920 | } else { | 9926 | } else { |
9921 | /* Example: "wait 1". mimic bash message */ | 9927 | /* Example: "wait 1". mimic bash message */ |
9922 | bb_error_msg("wait: pid %d is not a child of this shell", (int)pid); | 9928 | bb_error_msg("wait: pid %d is not a child of this shell", (int)pid); |
@@ -9925,7 +9931,6 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9925 | /* ??? */ | 9931 | /* ??? */ |
9926 | bb_perror_msg("wait %s", *argv); | 9932 | bb_perror_msg("wait %s", *argv); |
9927 | } | 9933 | } |
9928 | ret = 127; | ||
9929 | continue; /* bash checks all argv[] */ | 9934 | continue; /* bash checks all argv[] */ |
9930 | } | 9935 | } |
9931 | if (ret == 0) { | 9936 | if (ret == 0) { |
diff --git a/shell/hush_test/hush-misc/wait6.right b/shell/hush_test/hush-misc/wait6.right new file mode 100644 index 000000000..12decc137 --- /dev/null +++ b/shell/hush_test/hush-misc/wait6.right | |||
@@ -0,0 +1,2 @@ | |||
1 | 0 | ||
2 | 3 | ||
diff --git a/shell/hush_test/hush-misc/wait6.tests b/shell/hush_test/hush-misc/wait6.tests new file mode 100755 index 000000000..c23713199 --- /dev/null +++ b/shell/hush_test/hush-misc/wait6.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | # In bash, "wait $!" extracts correct exitcode even if bg task has already exited | ||
2 | # It prints 0, then 3: | ||
3 | (sleep 0; exit 3) & sleep 1 | ||
4 | echo $? | ||
5 | wait $! | ||
6 | echo $? | ||