From 3257f6b8d561cdf8805744d2a988b4bf414249fc Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 12 Jul 2009 15:09:56 +0000 Subject: 27134: Close SHTTY on exec. 27135: POSIX_JOBS leaves MONITOR on in subshell and doesn't save parent job table. --- ChangeLog | 11 ++++++++++- Doc/Zsh/options.yo | 22 +++++++++++++++++++--- Src/exec.c | 10 +++++++++- Src/init.c | 12 ++++++++++-- Src/jobs.c | 4 +++- 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 + + * 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 * 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) )( -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); -- cgit 1.4.1