Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug in sh emulation



On Fri, 09 Dec 2011 19:40:44 -0800
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> On Dec 9,  6:47pm, Bart Schaefer wrote:
> }
> } I don't see any recent changes in exec.c that would have
> } an effect on when a job is made ASYNC.
> 
> Unless this?
> 
> Anyway the change in question is really from 15301, which removes the
> ESUB_ASYNC from a bunch of entersubsh() calls.

Two of those have reappeared and reappearing the third doesn't seem to
help.

The problem appears to have come in between 4.3.10 and 4.3.11.  It's not
in 4.3.10 (2009-06-01) but is in a 4.3.10-dev-1 I have, which would be
just before I changed the version to 4.3.10-dev-2 (2010-07-25).

I think it's probably the set of changes around 27100 to 27109 that
allowed MONITOR to remain on in a subshell.  In particular,

    if (!isset(POSIXJOBS))
	opts[MONITOR] = 0;

(now) at line 974 of exec.c.  Commenting out the "if" line makes the
problem goes away.

Allowing MONITOR in subshells was done tentatively to see if it caused
problems.  I suppose the real surprise is it's taken over two years for
one to turn up.  So the bug is caused by a combination of having the
option set in a subshell and preexisting code that doesn't properly
support it.

> It's stuck in an infinite TTOU/CONT loop because for some reason it
> wants to attachtty(), which it can't because it's not the process leader
> (the parent shell still in the foreground is).

Note that this attachtty() is above the point where we set MONITOR to 0
if not POSIXJOBS, so this is occurring on a later fork --- indeed, we
need to remember that the problem only occurs with a pipeline in the
subshell.

My session / process group / controlling terminal understanding is
distinctly ropey.  Is the fix that we simply don't execute that code if
we've already executed it, i.e. subsh is already 1 when we get there
(see ultra-ultra-tentative patch --- we set subsh to 1 just after that)?
That fixes the problem, but that may be simply because we don't execute
the code that fails.  But what should actually happen if we have a
subshell of a subshell, i.e. a nested "( ... )"?  And what should the
group leader be set to at this point after a second fork?

P.S. somewhere high on the list of things we desperately need is a set
of interactive tests.

Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.205
diff -p -u -r1.205 exec.c
--- Src/exec.c	26 Oct 2011 18:48:13 -0000	1.205
+++ Src/exec.c	10 Dec 2011 18:09:26 -0000
@@ -925,7 +925,7 @@ entersubsh(int flags)
 		}
 	    }
 	}
-    } else if (thisjob != -1 && (flags & ESUB_PGRP)) {
+    } else if (thisjob != -1 && (flags & ESUB_PGRP) && !subsh) {
 	if (jobtab[list_pipe_job].gleader && (list_pipe || list_pipe_child)) {
 	    if (setpgrp(0L, jobtab[list_pipe_job].gleader) == -1 ||
 		killpg(jobtab[list_pipe_job].gleader, 0) == -1) {

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author