about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Src/init.c31
2 files changed, 33 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 5eaca9b3f..a65376061 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2002-11-04  Peter Stephenson  <pws@csr.com>
+
+	* 17859: Philippe Troin <phil@fifi.org>: Src/init.c: Better
+	handling of becoming process group leader in an interactive
+	process.  We could end up with two shells reading from the
+	terminal at once.
+
 2002-10-31  Wayne Davison  <wayned@users.sourceforge.net>
 
 	* 17881: Src/builtin.c, Src/params.c: made the elapsed time in the
diff --git a/Src/init.c b/Src/init.c
index c1c16873a..dca115eb6 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -457,19 +457,40 @@ init_io(void)
 	opts[USEZLE] = 0;
 
 #ifdef JOB_CONTROL
-    /* If interactive, make the shell the foreground process */
+    /* If interactive, make sure the shell is in the foreground and is the
+     * process group leader.
+     */
+    mypid = (zlong)getpid();
     if (opts[MONITOR] && interact && (SHTTY != -1)) {
 	if ((mypgrp = GETPGRP()) > 0) {
+	    sigset_t blockset, oldset;
+	    sigemptyset(&blockset);
+	    sigaddset(&blockset, SIGTTIN);
+	    sigaddset(&blockset, SIGTTOU);
+	    sigaddset(&blockset, SIGTSTP);
+	    oldset = signal_block(blockset);
 	    while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
-		sleep(1);	/* give parent time to change pgrp */
 		mypgrp = GETPGRP();
-		if (mypgrp == mypid)
-		    attachtty(mypgrp);
+		if (mypgrp == mypid) {
+		    signal_setmask(oldset);
+		    attachtty(mypgrp); /* Might generate SIGT* */
+		    signal_block(blockset);
+		}
 		if (mypgrp == gettygrp())
 		    break;
-		killpg(mypgrp, SIGTTIN);
+		signal_setmask(oldset);
+		read(0, NULL, 0); /* Might generate SIGT* */
+		signal_block(blockset);
 		mypgrp = GETPGRP();
 	    }
+	    if (mypgrp != mypid) {
+	        if (setpgrp(0, 0) == 0) {
+		    mypgrp = mypid;
+		    attachtty(mypgrp);
+                } else
+		    opts[MONITOR] = 0;
+	    }
+	    signal_setmask(oldset);
 	} else
 	    opts[MONITOR] = 0;
     } else