hush: rework "wait %jobspec" to work in non-interactive shells too
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 7 Nov 2016 23:59:29 +0000 (00:59 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 7 Nov 2016 23:59:29 +0000 (00:59 +0100)
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>
shell/ash_test/ash-misc/wait4.right [new file with mode: 0644]
shell/ash_test/ash-misc/wait4.tests [new file with mode: 0755]
shell/ash_test/ash-misc/wait5.right [new file with mode: 0644]
shell/ash_test/ash-misc/wait5.tests [new file with mode: 0755]
shell/hush.c
shell/hush_test/hush-misc/wait4.right [new file with mode: 0644]
shell/hush_test/hush-misc/wait4.tests [new file with mode: 0755]
shell/hush_test/hush-misc/wait5.right [new file with mode: 0644]
shell/hush_test/hush-misc/wait5.tests [new file with mode: 0755]

diff --git a/shell/ash_test/ash-misc/wait4.right b/shell/ash_test/ash-misc/wait4.right
new file mode 100644 (file)
index 0000000..f7987db
--- /dev/null
@@ -0,0 +1 @@
+Three:3
diff --git a/shell/ash_test/ash-misc/wait4.tests b/shell/ash_test/ash-misc/wait4.tests
new file mode 100755 (executable)
index 0000000..cc34059
--- /dev/null
@@ -0,0 +1,2 @@
+sleep 1 | (sleep 1;exit 3) & wait %1
+echo Three:$?
diff --git a/shell/ash_test/ash-misc/wait5.right b/shell/ash_test/ash-misc/wait5.right
new file mode 100644 (file)
index 0000000..82c9d56
--- /dev/null
@@ -0,0 +1,2 @@
+Zero:0
+Three:3
diff --git a/shell/ash_test/ash-misc/wait5.tests b/shell/ash_test/ash-misc/wait5.tests
new file mode 100755 (executable)
index 0000000..1b4762d
--- /dev/null
@@ -0,0 +1,5 @@
+sleep 0 | (sleep 0;exit 3) &
+sleep 1
+echo Zero:$?
+wait %1
+echo Three:$?
index 7683a3749eb61cf6a505d6bb47f85e48fc19a4ca..ddbf2f7d8b67666d2126c447c21dd3bb3694c053 100644 (file)
@@ -9586,7 +9586,6 @@ static int FAST_FUNC builtin_wait(char **argv)
 {
        int ret;
        int status;
-       struct pipe *wait_pipe = NULL;
 
        argv = skip_dash_dash(argv);
        if (argv[0] == NULL) {
@@ -9614,10 +9613,13 @@ static int FAST_FUNC builtin_wait(char **argv)
                if (errno || pid <= 0) {
 #if ENABLE_HUSH_JOB
                        if (argv[0][0] == '%') {
+                               struct pipe *wait_pipe;
                                wait_pipe = parse_jobspec(*argv);
                                if (wait_pipe) {
-                                       pid = - wait_pipe->pgrp;
-                                       goto do_wait;
+                                       ret = job_exited_or_stopped(wait_pipe);
+                                       if (ret < 0)
+                                               ret = wait_for_child_or_signal(wait_pipe, 0);
+                                       continue;
                                }
                        }
 #endif
@@ -9626,7 +9628,7 @@ static int FAST_FUNC builtin_wait(char **argv)
                        ret = EXIT_FAILURE;
                        continue; /* bash checks all argv[] */
                }
- IF_HUSH_JOB(do_wait:)
+
                /* Do we have such child? */
                ret = waitpid(pid, &status, WNOHANG);
                if (ret < 0) {
@@ -9652,20 +9654,13 @@ static int FAST_FUNC builtin_wait(char **argv)
                }
                if (ret == 0) {
                        /* 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 {
                        /* Yes, and it just exited */
-                       process_wait_result(NULL, ret, status);
+                       process_wait_result(NULL, pid, status);
                        ret = WEXITSTATUS(status);
                        if (WIFSIGNALED(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);
 
diff --git a/shell/hush_test/hush-misc/wait4.right b/shell/hush_test/hush-misc/wait4.right
new file mode 100644 (file)
index 0000000..f7987db
--- /dev/null
@@ -0,0 +1 @@
+Three:3
diff --git a/shell/hush_test/hush-misc/wait4.tests b/shell/hush_test/hush-misc/wait4.tests
new file mode 100755 (executable)
index 0000000..cc34059
--- /dev/null
@@ -0,0 +1,2 @@
+sleep 1 | (sleep 1;exit 3) & wait %1
+echo Three:$?
diff --git a/shell/hush_test/hush-misc/wait5.right b/shell/hush_test/hush-misc/wait5.right
new file mode 100644 (file)
index 0000000..82c9d56
--- /dev/null
@@ -0,0 +1,2 @@
+Zero:0
+Three:3
diff --git a/shell/hush_test/hush-misc/wait5.tests b/shell/hush_test/hush-misc/wait5.tests
new file mode 100755 (executable)
index 0000000..1b4762d
--- /dev/null
@@ -0,0 +1,5 @@
+sleep 0 | (sleep 0;exit 3) &
+sleep 1
+echo Zero:$?
+wait %1
+echo Three:$?