hush: rework "wait %jobspec" to work in non-interactive shells too

Also add tests. wait5.tests so far fails (but works for ash and dash).

function                                             old     new   delta
builtin_wait                                         305     283     -22

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2016-11-08 00:59:29 +01:00
parent 26ad94bedc
commit 02affb4afd
9 changed files with 28 additions and 13 deletions

View File

@ -0,0 +1 @@
Three:3

View File

@ -0,0 +1,2 @@
sleep 1 | (sleep 1;exit 3) & wait %1
echo Three:$?

View File

@ -0,0 +1,2 @@
Zero:0
Three:3

View File

@ -0,0 +1,5 @@
sleep 0 | (sleep 0;exit 3) &
sleep 1
echo Zero:$?
wait %1
echo Three:$?

View File

@ -9586,7 +9586,6 @@ static int FAST_FUNC builtin_wait(char **argv)
{ {
int ret; int ret;
int status; int status;
struct pipe *wait_pipe = NULL;
argv = skip_dash_dash(argv); argv = skip_dash_dash(argv);
if (argv[0] == NULL) { if (argv[0] == NULL) {
@ -9614,10 +9613,13 @@ static int FAST_FUNC builtin_wait(char **argv)
if (errno || pid <= 0) { if (errno || pid <= 0) {
#if ENABLE_HUSH_JOB #if ENABLE_HUSH_JOB
if (argv[0][0] == '%') { if (argv[0][0] == '%') {
struct pipe *wait_pipe;
wait_pipe = parse_jobspec(*argv); wait_pipe = parse_jobspec(*argv);
if (wait_pipe) { if (wait_pipe) {
pid = - wait_pipe->pgrp; ret = job_exited_or_stopped(wait_pipe);
goto do_wait; if (ret < 0)
ret = wait_for_child_or_signal(wait_pipe, 0);
continue;
} }
} }
#endif #endif
@ -9626,7 +9628,7 @@ static int FAST_FUNC builtin_wait(char **argv)
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
continue; /* bash checks all argv[] */ continue; /* bash checks all argv[] */
} }
IF_HUSH_JOB(do_wait:)
/* Do we have such child? */ /* Do we have such child? */
ret = waitpid(pid, &status, WNOHANG); ret = waitpid(pid, &status, WNOHANG);
if (ret < 0) { if (ret < 0) {
@ -9652,20 +9654,13 @@ static int FAST_FUNC builtin_wait(char **argv)
} }
if (ret == 0) { if (ret == 0) {
/* Yes, and it still runs */ /* Yes, and it still runs */
ret = wait_for_child_or_signal(wait_pipe, wait_pipe ? 0 : pid); ret = wait_for_child_or_signal(NULL, pid);
} else { } else {
/* Yes, and it just exited */ /* Yes, and it just exited */
process_wait_result(NULL, ret, status); process_wait_result(NULL, pid, status);
ret = WEXITSTATUS(status); ret = WEXITSTATUS(status);
if (WIFSIGNALED(status)) if (WIFSIGNALED(status))
ret = 128 + WTERMSIG(status); ret = 128 + WTERMSIG(status);
#if ENABLE_HUSH_JOB
if (wait_pipe) {
ret = job_exited_or_stopped(wait_pipe);
if (ret < 0)
goto do_wait;
}
#endif
} }
} while (*++argv); } while (*++argv);

View File

@ -0,0 +1 @@
Three:3

View File

@ -0,0 +1,2 @@
sleep 1 | (sleep 1;exit 3) & wait %1
echo Three:$?

View File

@ -0,0 +1,2 @@
Zero:0
Three:3

View File

@ -0,0 +1,5 @@
sleep 0 | (sleep 0;exit 3) &
sleep 1
echo Zero:$?
wait %1
echo Three:$?