summaryrefslogtreecommitdiff
path: root/Src/exec.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2011-12-12 19:25:02 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2011-12-12 19:25:02 +0000
commit93139f39f1efdb3f500b61b49045369e040770c0 (patch)
treed4c135d1233868e6affe0a18206be59fc0784710 /Src/exec.c
parent290ab11885d7a3beb1b4158b4d8e6e5ed2b33e11 (diff)
downloadzsh-93139f39f1efdb3f500b61b49045369e040770c0.tar.gz
zsh-93139f39f1efdb3f500b61b49045369e040770c0.zip
30000 plus some comments: Better POSIXJOBs behaviour.
Don't restore default SIGTTOU etc. behaviour if still doing job control. Only carry on doing job control in subshell if it's a real (...) subshell
Diffstat (limited to 'Src/exec.c')
-rw-r--r--Src/exec.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 2c644e6b7..9b3c50372 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -896,14 +896,16 @@ enum {
/* Release the process group if pid is the shell's process group */
ESUB_REVERTPGRP = 0x10,
/* Don't handle the MONITOR option even if previously set */
- ESUB_NOMONITOR = 0x20
+ ESUB_NOMONITOR = 0x20,
+ /* This is a subshell where job control is allowed */
+ ESUB_JOB_CONTROL = 0x40
};
/**/
static void
entersubsh(int flags)
{
- int sig, monitor;
+ int sig, monitor, job_control_ok;
if (!(flags & ESUB_KEEPTRAP))
for (sig = 0; sig < VSIGCOUNT; sig++)
@@ -911,6 +913,7 @@ entersubsh(int flags)
sig != SIGDEBUG && sig != SIGZERR)
unsettrap(sig);
monitor = isset(MONITOR);
+ job_control_ok = monitor && (flags & ESUB_JOB_CONTROL) && isset(POSIXJOBS);
if (flags & ESUB_NOMONITOR)
opts[MONITOR] = 0;
if (!isset(MONITOR)) {
@@ -938,6 +941,16 @@ entersubsh(int flags)
}
else if (!jobtab[thisjob].gleader ||
setpgrp(0L, jobtab[thisjob].gleader) == -1) {
+ /*
+ * This is the standard point at which a newly started
+ * process gets put into the foreground by taking over
+ * the terminal. Note that in normal circumstances we do
+ * this only from the process itself. This only works if
+ * we are still ignoring SIGTTOU at this point; in this
+ * case ignoring the signal has the special effect that
+ * the operation is allowed to work (in addition to not
+ * causing the shell to be suspended).
+ */
jobtab[thisjob].gleader = getpid();
if (list_pipe_job != thisjob &&
!jobtab[list_pipe_job].gleader)
@@ -959,7 +972,13 @@ entersubsh(int flags)
if ((flags & ESUB_REVERTPGRP) && getpid() == mypgrp)
release_pgrp();
shout = NULL;
- if (isset(MONITOR)) {
+ if (!job_control_ok) {
+ /*
+ * If this process is not goign to be doing job control,
+ * we don't want to do special things with the corresponding
+ * signals. If it is, we need to keep the special behaviour:
+ * see note about attachtty() above.
+ */
signal_default(SIGTTOU);
signal_default(SIGTTIN);
signal_default(SIGTSTP);
@@ -971,7 +990,7 @@ entersubsh(int flags)
}
if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED))
signal_default(SIGQUIT);
- if (!isset(POSIXJOBS))
+ if (!job_control_ok)
opts[MONITOR] = 0;
opts[USEZLE] = 0;
zleactive = 0;
@@ -2829,6 +2848,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP;
if ((type != WC_SUBSH) && !(how & Z_ASYNC))
flags |= ESUB_KEEPTRAP;
+ if (type == WC_SUBSH && !(how & Z_ASYNC))
+ flags |= ESUB_JOB_CONTROL;
entersubsh(flags);
close(synch[1]);
forked = 1;