summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.stephenson@samsung.com>2019-10-28 11:56:19 +0000
committerPeter Stephenson <p.stephenson@samsung.com>2019-10-28 11:56:19 +0000
commit8c25d92e11b57aad056d34af3c2269aad586f659 (patch)
treeda03727ef7d16d338a848c06833fe8f979d5d04f
parent5be28dac5d07d779be265a69943225fd9c87068a (diff)
downloadzsh-8c25d92e11b57aad056d34af3c2269aad586f659.tar.gz
zsh-8c25d92e11b57aad056d34af3c2269aad586f659.tar.xz
zsh-8c25d92e11b57aad056d34af3c2269aad586f659.zip
44864: Avoid inifinite loop in tty init.
If we can't grab the terminal in interactive mode, give
up after 100 goes.  This is a completely arbitrary choice;
we simply don't know what in the system could change the
result of looping further.
-rw-r--r--ChangeLog4
-rw-r--r--Src/jobs.c18
2 files changed, 20 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 479544208..87adb1fe9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2019-10-28  Peter Stephenson  <p.stephenson@samsung.com>
 
+	* 44864: Src/jobs.c: Avoid infinite loop in interactive mode
+	when trying to grab terminal.  Fail after 100 goes (arbitrary
+	choice).
+
 	* Sebastian: 44865: configure.ac: Try harder to link in curses
 	even if not needed for termcap variables.
 
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) {