[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] [PATCH] TIOCNOTTY messes the controlling tty



On 12/09/2014 19:34, Jo Even Skarstein wrote:
The great thing about these mails from you is that they're always
followed by a "success!" mail :) Thanks for being so persistent Vincent.

I'm not sure if this is always true...
But this time, you're right :D

Short story:
ioctl(TIOCNOTTY) is supposed to detach the calling process from its controlling terminal. Special care happens when the process is the session leader (i.e. bash). But in FreeMiNT, the tty was messed even if the process was not a session leader (i.e. dhclient, sshd...). Then the calling bash was affected, closing immediately.

Explanations:
A process has normally a controlling terminal (the one referred by /dev/tty, revealed by the "tty" command), and that terminal is attached to a group of process. ioctl(TIOCNOTTY) detaches the process from its controlling terminal. If the process is a session leader, it also detaches the controlling terminal from its process group. But there was bug: the terminal was always detached from its process group, including when it was called by a standard child process (i.e. when a daemon forks).

Then the status of the tty (attached to a process group, or not) is checked in read(). After starting a daemon, bash uses read() to read the next command line. If the terminal has been detached, read() returns EIO and bash exits immediately.

Curiously, when the terminal was broken by TIOCNOTTY, it only affected bash login shells, not secondary shells. This is because a login shell ignores SIGTTIN, while secondary shells set a handler for that signal. This affects the read() logic.

Of course, this bug affected all the FreeMiNT variants. I can't understand why I initially thought that only the FireBee was affected. Probably wrong testcases. I struggled a lot, due to those wanderings.

The attached patch fixes the problem in the kernel, and it is safe. With that, you can start any daemon (dhclient, sshd...) and your terminal will not close anymore (it affected both TosWin2 and ssh remote shells).

Alan, please commit!

TIOCNOTTY.patch
Do not close the terminal when starting a daemon. Contributed by Vincent Riviere.

--
Vincent Rivière
diff -aurN -x CVS freemint.orig/sys/tty.c freemint/sys/tty.c
--- freemint.orig/sys/tty.c	2013-05-15 21:16:43.218750000 +0200
+++ freemint/sys/tty.c	2014-09-18 21:25:50.984375000 +0200
@@ -1227,13 +1227,12 @@
 				{
 					killgroup (tty->pgrp, SIGHUP, 0);
 					killgroup (tty->pgrp, SIGCONT, 0);
+
+					tty->pgrp = 0;
+					DEBUG (("TIOCNOTTY: assigned tty->pgrp = %i", tty->pgrp));
 				}
-				
 			}
 			
-			tty->pgrp = 0;
-			DEBUG (("TIOCNOTTY: assigned tty->pgrp = %i", tty->pgrp));
-			
 			do_close (get_curproc(), get_curproc()->p_fd->control);
 			get_curproc()->p_fd->control = NULL;