[git commit] cttyhack: check sysfs for the name of the active console

Denys Vlasenko vda.linux at googlemail.com
Wed Jul 13 07:30:36 UTC 2011


commit: http://git.busybox.net/busybox/commit/?id=064e99646a233240e91f453ba49f6baeab7c2c70
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/cttyhack.c |   79 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/shell/cttyhack.c b/shell/cttyhack.c
index d1ac2cd..522a1ba 100644
--- a/shell/cttyhack.c
+++ b/shell/cttyhack.c
@@ -14,18 +14,22 @@
 //config:	bool "cttyhack"
 //config:	default y
 //config:	help
-//config:	  One common problem reported on the mailing list is "can't access tty;
-//config:	  job control turned off" error message which typically appears when
-//config:	  one tries to use shell with stdin/stdout opened to /dev/console.
+//config:	  One common problem reported on the mailing list is the "can't
+//config:	  access tty; job control turned off" error message, which typically
+//config:	  appears when one tries to use a shell with stdin/stdout on
+//config:	  /dev/console.
 //config:	  This device is special - it cannot be a controlling tty.
 //config:
-//config:	  Proper solution is to use correct device instead of /dev/console.
+//config:	  The proper solution is to use the correct device instead of
+//config:	  /dev/console.
 //config:
-//config:	  cttyhack provides "quick and dirty" solution to this problem.
+//config:	  cttyhack provides a "quick and dirty" solution to this problem.
 //config:	  It analyzes stdin with various ioctls, trying to determine whether
 //config:	  it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
-//config:	  If it detects one, it closes stdin/out/err and reopens that device.
-//config:	  Then it executes given program. Opening the device will make
+//config:	  On Linux it also checks sysfs for a pointer to the active console.
+//config:	  If cttyhack is able to find the real console device, it closes
+//config:	  stdin/out/err and reopens that device.
+//config:	  Then it executes the given program. Opening the device will make
 //config:	  that device a controlling tty. This may require cttyhack
 //config:	  to be a session leader.
 //config:
@@ -115,33 +119,46 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
 		close(fd);
 	} else {
 		/* We don't have ctty (or don't have "/dev/tty" node...) */
-		if (0) {}
-#ifdef TIOCGSERIAL
-		else if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
-			/* this is a serial console */
-			sprintf(console + 8, "S%d", u.sr.line);
-		}
-#endif
+		do {
 #ifdef __linux__
-		else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
-			/* this is linux virtual tty */
-			sprintf(console + 8, "S%d" + 1, u.vt.v_active);
-		}
+			int s = open_read_close("/sys/class/tty/console/active",
+				console + 5, sizeof(console) - 5 - 1);
+			if (s > 0) {
+				/* found active console via sysfs (Linux 2.6.38+) */
+				console[5 + s] = '\0';
+				break;
+			}
+
+			if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
+				/* this is linux virtual tty */
+				sprintf(console + 8, "S%d" + 1, u.vt.v_active);
+				break;
+			}
 #endif
-		if (console[8]) {
-			fd = xopen(console, O_RDWR);
-			//bb_error_msg("switching to '%s'", console);
-			dup2(fd, 0);
-			dup2(fd, 1);
-			dup2(fd, 2);
-			while (fd > 2)
-				close(fd--);
-			/* Some other session may have it as ctty,
-			 * steal it from them:
-			 */
-			ioctl(0, TIOCSCTTY, 1);
-		}
+#ifdef TIOCGSERIAL
+			if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
+				/* this is a serial console, asuming it is named /dev/ttySn */
+				sprintf(console + 8, "S%d", u.sr.line);
+				break;
+			}
+#endif
+			/* nope, could not find it */
+			goto ret;
+		} while (0);
+
+		fd = xopen(console, O_RDWR);
+		//bb_error_msg("switching to '%s'", console);
+		dup2(fd, 0);
+		dup2(fd, 1);
+		dup2(fd, 2);
+		while (fd > 2)
+			close(fd--);
+		/* Some other session may have it as ctty,
+		 * steal it from them:
+		 */
+		ioctl(0, TIOCSCTTY, 1);
 	}
 
+ret:
 	BB_EXECVP_or_die(argv);
 }
-- 
1.7.3.4



More information about the busybox-cvs mailing list