summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2017-07-04 09:40:45 +0100
committerPeter Stephenson <pws@zsh.org>2017-07-04 09:40:45 +0100
commita955065cda3dcaa80058520ba55dc0bf5c8d3f08 (patch)
tree943ee67f8b9141d65b5bcfacba9d84bf721681bc
parentcdd9402224da17e90b674a135e0183291c3f38ec (diff)
downloadzsh-a955065cda3dcaa80058520ba55dc0bf5c8d3f08.tar.gz
zsh-a955065cda3dcaa80058520ba55dc0bf5c8d3f08.tar.xz
zsh-a955065cda3dcaa80058520ba55dc0bf5c8d3f08.zip
Delay processing "disown" for superjob.
This is a job forked from the current shell when a job partly
running from the current shell was suspended.  When all associated
processes started from the main shell are finished the job is
continued and at this point the disown can complete.
-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 */