about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Doc/Zsh/jobs.yo6
-rw-r--r--Src/jobs.c8
-rw-r--r--Src/zsh.h1
4 files changed, 18 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a080f4ae..d5ff3f5e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2017-07-04  Peter Stephenson  <p.stephenson@samsung.com>
 
+	* 41391: Doc/Zsh/jobs.yo, Src/jobs.c, Src/zsh.h: delay disown
+	for superjob.
+
 	* Maxime de Roucy: 41385: Src/Zle/complist.c: Avoid invalid
 	access with isearch in completion list.
 
diff --git a/Doc/Zsh/jobs.yo b/Doc/Zsh/jobs.yo
index 6262dd244..70559f2d8 100644
--- a/Doc/Zsh/jobs.yo
+++ b/Doc/Zsh/jobs.yo
@@ -49,6 +49,12 @@ in the parent shell.  Thus the behaviour is different from the case
 where the function was never suspended.  Zsh is different from many
 other shells in this regard.
 
+One additional side effect is that use of tt(disown) with a job
+created by suspending shell code in this fashion is delayed: the
+job can only be disowned once any process started from the parent
+shell has terminated.  At that point, the disowned job disappears
+silently from the job list.
+
 The same behaviour is found when the shell is executing code as the
 right hand side of a pipeline or any complex shell construct such as
 tt(if), tt(for), etc., in order that the entire block of code
diff --git a/Src/jobs.c b/Src/jobs.c
index 32f7daab9..66dfb5a7e 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -277,6 +277,10 @@ handle_sub(int job, int fg)
 		(!jn->procs->next || cp || jn->procs->pid != jn->gleader))
 		attachtty(jn->gleader);
 	    kill(sj->other, SIGCONT);
+	    if (jn->stat & STAT_DISOWN)
+	    {
+		deletejob(jn, 1);
+	    }
 	}
 	curjob = jn - jobtab;
     } else if (sj->stat & STAT_STOPPED) {
@@ -2375,6 +2379,10 @@ bin_fg(char *name, char **argv, Options ops, int func)
 	    printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2);
 	    break;
 	case BIN_DISOWN:
+	    if (jobtab[job].stat & STAT_SUPERJOB) {
+		jobtab[job].stat |= STAT_DISOWN;
+		continue;
+	    }
 	    if (jobtab[job].stat & STAT_STOPPED) {
 		char buf[20], *pids = "";
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 137b2a52a..a5b4d8fc4 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1029,6 +1029,7 @@ struct job {
 #define STAT_BUILTIN    (0x4000) /* job at tail of pipeline is a builtin */
 #define STAT_SUBJOB_ORPHANED (0x8000)
                                  /* STAT_SUBJOB with STAT_SUPERJOB exited */
+#define STAT_DISOWN     (0x10000) /* STAT_SUPERJOB with disown pending */
 
 #define SP_RUNNING -1		/* fake status for jobs currently running */