diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-28 22:39:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-28 22:39:12 +0200 |
commit | 9db74e49e5b462089c6eec0182d819c0d4708e57 (patch) | |
tree | 79195e02400d0b0bd17f409325db01cf79f03dd6 | |
parent | 7e6753609d102b68a625072fb1660065246a54e2 (diff) | |
download | busybox-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.c | 18 |
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 | } |