summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--Src/exec.c2
-rw-r--r--Src/init.c1
-rw-r--r--Src/jobs.c20
-rw-r--r--Src/signals.c10
5 files changed, 45 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 834f339db..103dbccf3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-12-02 Peter Stephenson <pws@csr.com>
+
+ * 27442 plus tweak: Src/exec.c, Src/init.c, Src/jobs.c,
+ Src/signals.c: return status for last background job from
+ wait even if it's already exited, but only if POSIX_JOBS
+ is set.
+
2009-12-01 Peter Stephenson <p.w.stephenson@ntlworld.com>
* Alexey: 27445: Completion/Unix/Command/_ruby: argument can be
@@ -5,6 +12,10 @@
2009-11-30 Peter Stephenson <pws@csr.com>
+ * 27442: Src/exec.c, Src/init.c, Src/job.s,c Src/signals.c:
+ add lastpid_status to record status of last background job
+ even after it's exited.
+
* 27441: Doc/Zsh/mod_complist.yo, Src/Zle/complist.c: add "sa"
highlight code for suffix aliases.
@@ -12409,5 +12420,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4827 $
+* $Revision: 1.4828 $
*****************************************************
diff --git a/Src/exec.c b/Src/exec.c
index 2263bd640..172d302da 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2727,6 +2727,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
#endif
if (how & Z_ASYNC) {
lastpid = (zlong) pid;
+ /* indicate it's possible to set status for lastpid */
+ lastpid_status = -2L;
} else if (!jobtab[thisjob].stty_in_env && varspc) {
/* search for STTY=... */
Wordcode p = varspc;
diff --git a/Src/init.c b/Src/init.c
index be1055a53..cf5a6074d 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -913,6 +913,7 @@ setupvals(void)
bufstack = znewlinklist();
hsubl = hsubr = NULL;
lastpid = 0;
+ lastpid_status = -1L;
bshin = SHIN ? fdopen(SHIN, "r") : stdin;
if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) {
#ifdef _IONBF
diff --git a/Src/jobs.c b/Src/jobs.c
index d0916174f..9b7b053ee 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -104,6 +104,15 @@ int prev_errflag, prev_breaks, errbrk_saved;
/**/
int numpipestats, pipestats[MAX_PIPESTATS];
+/*
+ * The status associated with the process lastpid.
+ * -1 if not set and no associated lastpid
+ * -2 if lastpid is set and status isn't yet
+ * else the value returned by wait().
+ */
+/**/
+long lastpid_status;
+
/* Diff two timevals for elapsed-time computations */
/**/
@@ -1109,6 +1118,14 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime)
{
Process pn, *pnlist;
+ if (pid == lastpid && lastpid_status != -2L) {
+ /*
+ * The status for the previous lastpid is invalid.
+ * Presumably process numbers have wrapped.
+ */
+ lastpid_status = -1L;
+ }
+
DPUTS(thisjob == -1, "No valid job in addproc.");
pn = (Process) zshcalloc(sizeof *pn);
pn->pid = pid;
@@ -1845,6 +1862,9 @@ bin_fg(char *name, char **argv, Options ops, int func)
retval = waitforpid(pid, 1);
if (!retval)
retval = lastval2;
+ } else if (isset(POSIXJOBS) &&
+ pid == lastpid && lastpid_status >= 0L) {
+ retval = (int)lastpid_status;
} else {
zwarnnam(name, "pid %d is not a child of this shell", pid);
/* presumably lastval2 doesn't tell us a heck of a lot? */
diff --git a/Src/signals.c b/Src/signals.c
index 4bc1de016..f67a3e8ca 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -530,6 +530,7 @@ zhandler(int sig)
* Find the process and job containing this pid and
* update it.
*/
+ pn = NULL;
if (findproc(pid, &jn, &pn, 0)) {
#if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE)
struct timezone dummy_tz;
@@ -551,6 +552,15 @@ zhandler(int sig)
*/
get_usage();
}
+ /*
+ * Remember the status associated with $!, so we can
+ * wait for it even if it's exited. This value is
+ * only used if we can't find the PID in the job table,
+ * so it doesn't matter that the value we save here isn't
+ * useful until the process has exited.
+ */
+ if (pn != NULL && pid == lastpid && lastpid_status != -1L)
+ lastpid_status = lastval2;
}
break;