summary refs log tree commit diff
diff options
context:
space:
mode:
authorMartijn Dekker <martijn@inlv.org>2018-12-25 20:44:51 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2018-12-30 18:11:43 +0000
commit2d056ebc31231fa40b85a89f54e59c3219ced531 (patch)
tree43ad4a9c8ab06ca511a6d9b6a15bee3150b39304
parent4215fcb1075f4608cf039ae9b593b07580060a70 (diff)
downloadzsh-2d056ebc31231fa40b85a89f54e59c3219ced531.tar.gz
zsh-2d056ebc31231fa40b85a89f54e59c3219ced531.tar.xz
zsh-2d056ebc31231fa40b85a89f54e59c3219ced531.zip
43945 (tweaked to remove test failure, noted in test):
Fix exit statuses from wait for POSIX_BUILTINS mode.
Also add tests.
-rw-r--r--Doc/Zsh/builtins.yo2
-rw-r--r--Src/jobs.c23
-rw-r--r--Test/A05execution.ztst53
3 files changed, 68 insertions, 10 deletions
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index fd29ca3a5..cc9832379 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -2362,6 +2362,8 @@ then all currently active child processes are waited for.
 Each var(job) can be either a job specification or the process ID
 of a job in the job table.
 The exit status from this command is that of the job waited for.
+If var(job) represents an unknown job or process ID, a warning is printed
+(unless the tt(POSIX_BUILTINS) option is set) and the exit status is 127.
 
 It is possible to wait for recent processes (specified by process ID,
 not by job) that were running in the background even if the process has
diff --git a/Src/jobs.c b/Src/jobs.c
index ed9f81f26..73d7f26da 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1910,7 +1910,7 @@ getjob(const char *s, const char *prog)
     /* "%%", "%+" and "%" all represent the current job */
     if (*s == '%' || *s == '+' || !*s) {
 	if (curjob == -1) {
-	    if (prog)
+	    if (prog && !isset(POSIXBUILTINS))
 		zwarnnam(prog, "no current job");
 	    returnval = -1;
 	    goto done;
@@ -1921,7 +1921,7 @@ getjob(const char *s, const char *prog)
     /* "%-" represents the previous job */
     if (*s == '-') {
 	if (prevjob == -1) {
-	    if (prog)
+	    if (prog && !isset(POSIXBUILTINS))
 		zwarnnam(prog, "no previous job");
 	    returnval = -1;
 	    goto done;
@@ -1944,7 +1944,7 @@ getjob(const char *s, const char *prog)
 	    returnval = jobnum;
 	    goto done;
 	}
-	if (prog)
+	if (prog && !isset(POSIXBUILTINS))
 	    zwarnnam(prog, "%%%s: no such job", s);
 	returnval = -1;
 	goto done;
@@ -1962,7 +1962,7 @@ getjob(const char *s, const char *prog)
 			returnval = jobnum;
 			goto done;
 		    }
-	if (prog)
+	if (prog && !isset(POSIXBUILTINS))
 	    zwarnnam(prog, "job not found: %s", s);
 	returnval = -1;
 	goto done;
@@ -1976,7 +1976,8 @@ getjob(const char *s, const char *prog)
     }
     /* if we get here, it is because none of the above succeeded and went
     to done */
-    zwarnnam(prog, "job not found: %s", s);
+    if (!isset(POSIXBUILTINS))
+	zwarnnam(prog, "job not found: %s", s);
     returnval = -1;
   done:
     return returnval;
@@ -2375,9 +2376,10 @@ bin_fg(char *name, char **argv, Options ops, int func)
 		    }
 		}
 	    } else if ((retval = getbgstatus(pid)) < 0) {
-		zwarnnam(name, "pid %d is not a child of this shell", pid);
+		if (!isset(POSIXBUILTINS))
+		    zwarnnam(name, "pid %d is not a child of this shell", pid);
 		/* presumably lastval2 doesn't tell us a heck of a lot? */
-		retval = 1;
+		retval = 127;
 	    }
 	    thisjob = ocj;
 	    continue;
@@ -2391,15 +2393,16 @@ bin_fg(char *name, char **argv, Options ops, int func)
 	job = (*argv) ? getjob(*argv, name) : firstjob;
 	firstjob = -1;
 	if (job == -1) {
-	    retval = 1;
+	    retval = 127;
 	    break;
 	}
 	jstat = oldjobtab ? oldjobtab[job].stat : jobtab[job].stat;
 	if (!(jstat & STAT_INUSE) ||
 	    (jstat & STAT_NOPRINT)) {
-	    zwarnnam(name, "%s: no such job", *argv);
+	    if (!isset(POSIXBUILTINS))
+		zwarnnam(name, "%s: no such job", *argv);
 	    unqueue_signals();
-	    return 1;
+	    return 127;
 	}
         /* If AUTO_CONTINUE is set (automatically make stopped jobs running
          * on disown), we actually do a bg and then delete the job table entry. */
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
index 5d3d460df..edc561582 100644
--- a/Test/A05execution.ztst
+++ b/Test/A05execution.ztst
@@ -341,3 +341,56 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline
 >17
 >19
 
+# Test 'wait' for unknown job/process ID.
+  wait 1
+  echo $?
+  wait %%
+  echo $?
+  wait %+
+  echo $?
+  wait %-
+  echo $?
+  wait %1
+  echo $?
+  wait %foo
+  echo $?
+  wait %\?bar
+127:'wait' exit status and warning for unknown ID
+>127
+>127
+>127
+>127
+>127
+>127
+?(eval):wait:1: pid 1 is not a child of this shell
+?(eval):wait:3: %%: no such job
+?(eval):wait:5: %+: no such job
+?(eval):wait:7: %-: no such job
+?(eval):wait:9: %1: no such job
+?(eval):wait:11: job not found: foo
+?(eval):wait:13: job not found: ?bar
+
+# Test 'wait' for unknown job/process ID (POSIX mode).
+  (setopt POSIX_BUILTINS
+  wait 1
+  echo $?
+  wait %%
+  echo $?
+  wait %+
+  echo $?
+  wait %-
+  echo $?
+  wait %1
+  echo $?
+  wait %foo
+  echo $?
+  wait %\?bar)
+127:'wait' exit status for unknown ID (POSIX mode)
+>127
+>0
+>127
+>127
+>127
+>127
+# TBD: the 0 above is believed to be bogus and should also be turned
+# into 127 when the ccorresponding bug is fixed in the main shell.