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

Re: zsh hanging when exec'd from bash at login



On Mon, 2019-10-21 at 21:33 -0500, dana wrote:
> It seems to be hanging in acquire_pgrp() (see annotated strace below). I guess
> it's trying to make itself the process group leader and take over the TTY? But
> i don't understand what it's getting stuck on

There is a possible infinite loop there in the case of an interactive
shell.  It would probably be safer to change this.  Presumably that will
leave job control dysfunctional --- but there's already a check just
after the loop that unsets the MONITOR option in that case, so that
should already fail safe.

The worry is that the infinite loop is making things robust in the case
where we eventually can grab the tty --- we don't know what might be
going on elsewhere in the system that causes it to be set up late.  I've
left the loop count at 100 for this reason, but that's just a finger in
the air.  Any other suggestions are welcome.

That doesn't fix the underlying issue, but on the whole it seems unlikely
that's possible at this point; that's a rather murkier question.

> (Maybe should move this to workers)

I've done that.

pws

diff --git a/Src/jobs.c b/Src/jobs.c
index 50751decb..c06cb9c79 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -2933,6 +2933,7 @@ acquire_pgrp(void)
 	sigaddset(&blockset, SIGTTOU);
 	sigaddset(&blockset, SIGTSTP);
 	oldset = signal_block(blockset);
+	int loop_count = 0;
 	while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
 	    mypgrp = GETPGRP();
 	    if (mypgrp == mypid) {
@@ -2948,8 +2949,21 @@ acquire_pgrp(void)
 	    if (read(0, NULL, 0) != 0) {} /* Might generate SIGT* */
 	    signal_block(blockset);
 	    mypgrp = GETPGRP();
-	    if (mypgrp == lastpgrp && !interact)
-		break; /* Unlikely that pgrp will ever change */
+	    if (mypgrp == lastpgrp) {
+		if (!interact)
+		    break; /* Unlikely that pgrp will ever change */
+		if (++loop_count == 100)
+		{
+		    /*
+		     * It's time to give up.  The count is arbitrary;
+		     * this is just to fix up unusual cases, so it's
+		     * left large in an attempt not to break normal
+		     * cases where there's some delay in the system
+		     * setting up the terminal.
+		     */
+		    break;
+		}
+	    }
 	    lastpgrp = mypgrp;
 	}
 	if (mypgrp != mypid) {


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