aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-28 22:39:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-28 22:39:12 +0200
commit9db74e49e5b462089c6eec0182d819c0d4708e57 (patch)
tree79195e02400d0b0bd17f409325db01cf79f03dd6
parent7e6753609d102b68a625072fb1660065246a54e2 (diff)
downloadbusybox-w32-9db74e49e5b462089c6eec0182d819c0d4708e57.tar.gz
busybox-w32-9db74e49e5b462089c6eec0182d819c0d4708e57.tar.bz2
busybox-w32-9db74e49e5b462089c6eec0182d819c0d4708e57.zip
hush: fix "(sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?"
"wait $!" may be just a bit too late: backgrounded $! is gone. Do not bomb out in this case. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 1f8a3e607..7c2f157b8 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -9529,13 +9529,22 @@ static int FAST_FUNC builtin_wait(char **argv)
9529 if (errno || pid <= 0) { 9529 if (errno || pid <= 0) {
9530 /* mimic bash message */ 9530 /* mimic bash message */
9531 bb_error_msg("wait: '%s': not a pid or valid job spec", *argv); 9531 bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
9532 return EXIT_FAILURE; 9532 ret = EXIT_FAILURE;
9533 continue; /* bash checks all argv[] */
9533 } 9534 }
9534 /* Do we have such child? */ 9535 /* Do we have such child? */
9535 ret = waitpid(pid, &status, WNOHANG); 9536 ret = waitpid(pid, &status, WNOHANG);
9536 if (ret < 0) { 9537 if (ret < 0) {
9537 /* No */ 9538 /* No */
9538 if (errno == ECHILD) { 9539 if (errno == ECHILD) {
9540 if (G.last_bg_pid > 0 && pid == G.last_bg_pid) {
9541 /* "wait $!" but last bg task has already exited. Try:
9542 * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
9543 * In bash it prints exitcode 0, then 3.
9544 */
9545 ret = 0; /* FIXME */
9546 continue;
9547 }
9539 /* Example: "wait 1". mimic bash message */ 9548 /* Example: "wait 1". mimic bash message */
9540 bb_error_msg("wait: pid %d is not a child of this shell", (int)pid); 9549 bb_error_msg("wait: pid %d is not a child of this shell", (int)pid);
9541 } else { 9550 } else {
@@ -9543,7 +9552,9 @@ static int FAST_FUNC builtin_wait(char **argv)
9543 bb_perror_msg("wait %s", *argv); 9552 bb_perror_msg("wait %s", *argv);
9544 } 9553 }
9545 ret = 127; 9554 ret = 127;
9546 } else if (ret == 0) { 9555 continue; /* bash checks all argv[] */
9556 }
9557 if (ret == 0) {
9547 /* Yes, and it still runs */ 9558 /* Yes, and it still runs */
9548 ret = wait_for_child_or_signal(pid); 9559 ret = wait_for_child_or_signal(pid);
9549 } else { 9560 } else {
@@ -9553,8 +9564,7 @@ static int FAST_FUNC builtin_wait(char **argv)
9553 if (WIFSIGNALED(status)) 9564 if (WIFSIGNALED(status))
9554 ret = 128 + WTERMSIG(status); 9565 ret = 128 + WTERMSIG(status);
9555 } 9566 }
9556 argv++; 9567 } while (*++argv);
9557 } while (*argv);
9558 9568
9559 return ret; 9569 return ret;
9560} 9570}