about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-07-12 15:09:56 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-07-12 15:09:56 +0000
commit3257f6b8d561cdf8805744d2a988b4bf414249fc (patch)
tree0fd39eb26cadc23d17368c91217067816745c331
parent653d6a0dd95668eb3ad0d92de985cf14c1f65a8d (diff)
downloadzsh-3257f6b8d561cdf8805744d2a988b4bf414249fc.tar.gz
zsh-3257f6b8d561cdf8805744d2a988b4bf414249fc.tar.xz
zsh-3257f6b8d561cdf8805744d2a988b4bf414249fc.zip
27134: Close SHTTY on exec.
27135: POSIX_JOBS leaves MONITOR on in subshell and doesn't save
parent job table.
-rw-r--r--ChangeLog11
-rw-r--r--Doc/Zsh/options.yo22
-rw-r--r--Src/exec.c10
-rw-r--r--Src/init.c12
-rw-r--r--Src/jobs.c4
5 files changed, 51 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 52e2dc22e..8647869c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-07-12  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 27135: Doc/Zsh/options.yo, Src/exec.c, Src/jobs.c: expand
+	POSIX_JOBS option to leave MONITOR on in subshell and not to
+	report the parent shell's jobs.
+
+	* 27134: Src/exec.c, Src/init.c: improve 27131 by setting
+	FD_CLOEXEC for SHTTY or closing it by hand when executing.
+
 2009-07-11  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
 	* 27131: Src/exec.c, Src/jobs.c: tentative attempt to
@@ -11971,5 +11980,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4738 $
+* $Revision: 1.4739 $
 *****************************************************
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 7a2c732d1..74b5c8f86 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1280,10 +1280,26 @@ pindex(NO_POSIX_JOBS)
 pindex(NOPOSIXJOBS)
 cindex(bg, output in POSIX format)
 cindex(fg, output in POSIX format)
+cindex(job control, in subshell)
+cindex(jobs, output in subshell)
 item(tt(POSIX_JOBS) <K> <S>)(
-When putting jobs in the background or foreground with tt(bg) or tt(fg),
-just print the text of the job as required by POSIX,
-rather than the full information that would be output by tt(jobs).
+This option makes job control more compliant with the POSIX standard.
+
+When the option is not set, the tt(MONITOR) option is unset on entry to
+subshells, so that job control is no longer active.  When the option is
+set, the tt(MONITOR) option and job control remain active in the
+subshell, but note that the subshell has no access to jobs in the parent
+shell.
+
+When the option is not set, jobs put in the background or foreground
+with tt(bg) or tt(fg) are displayed with the same information that would
+be reported by tt(jobs).  When the option is set, only the text is
+printed.  The output from tt(jobs) itself is not affected by the option.
+
+When the option is not set, job information from the parent
+shell is saved for output within a subshell (for example, within a
+pipeline).  When the option is set, the output of tt(jobs) is empty
+until a job is started within the subshell.
 )
 enditem()
 
diff --git a/Src/exec.c b/Src/exec.c
index 004459abf..e68237948 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -595,6 +595,12 @@ execute(LinkList args, int flags, int defpath)
      * here, which should be visible to external processes.
      */
     closem(FDT_XTRACE);
+#ifndef FD_CLOEXEC
+    if (SHTTY != -1) {
+	close(SHTTY);
+	SHTTY = -1;
+    }
+#endif
     child_unblock();
     if ((int) strlen(arg0) >= PATH_MAX) {
 	zerr("command too long: %s", arg0);
@@ -944,7 +950,9 @@ entersubsh(int flags)
     }
     if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED))
 	signal_default(SIGQUIT);
-    opts[MONITOR] = opts[USEZLE] = 0;
+    if (!isset(POSIXJOBS))
+	opts[MONITOR] = 0;
+    opts[USEZLE] = 0;
     zleactive = 0;
     if (flags & ESUB_PGRP)
 	clearjobtab(monitor);
diff --git a/Src/init.c b/Src/init.c
index b807f0659..be1055a53 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -480,8 +480,16 @@ init_io(void)
     if (SHTTY == -1) {
 	zsfree(ttystrname);
 	ttystrname = ztrdup("");
-    } else if (!ttystrname) {
-	ttystrname = ztrdup("/dev/tty");
+    } else {
+#ifdef FD_CLOEXEC
+	long fdflags = fcntl(SHTTY, F_GETFD, 0);
+	if (fdflags != (long)-1) {
+	    fdflags |= FD_CLOEXEC;
+	    fcntl(SHTTY, F_SETFD, fdflags);
+	}
+#endif
+	if (!ttystrname)
+	    ttystrname = ztrdup("/dev/tty");
     }
 
     /* We will only use zle if shell is interactive, *
diff --git a/Src/jobs.c b/Src/jobs.c
index 8e48ed4b8..df7d9d689 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1292,6 +1292,8 @@ clearjobtab(int monitor)
 {
     int i;
 
+    if (isset(POSIXJOBS))
+	oldmaxjob = 0;
     for (i = 1; i <= maxjob; i++) {
 	/*
 	 * See if there is a jobtable worth saving.
@@ -1299,7 +1301,7 @@ clearjobtab(int monitor)
 	 * once for each subshell of a shell with job control,
 	 * so doesn't create a leak.
 	 */
-	if (monitor && jobtab[i].stat)
+	if (monitor && !isset(POSIXJOBS) && jobtab[i].stat)
 	    oldmaxjob = i+1;
 	else if (jobtab[i].stat & STAT_INUSE)
 	    freejob(jobtab + i, 0);