---
 login-utils/sulogin.c |   17 ++++++++++++-----
 term-utils/agetty.c   |   23 +++++++++++------------
 2 files changed, 23 insertions(+), 17 deletions(-)

--- login-utils/sulogin.c
+++ login-utils/sulogin.c	2014-05-08 08:01:13.102622002 +0000
@@ -49,6 +49,11 @@
 # include <selinux/get_context_list.h>
 #endif
 
+#ifdef __linux__
+# include <sys/kd.h>
+# include <sys/param.h>
+#endif
+
 #include "c.h"
 #include "closestream.h"
 #include "nls.h"
@@ -142,10 +147,14 @@ static void tcinit(struct console *con)
 		return;
 	}
 
-	/* Handle serial lines here */
-	if (ioctl(fd, TIOCMGET, (char *) &mode) == 0) {
+	/* Handle lines other than virtual consoles here */
+#if defined(KDGKBMODE)
+	if (ioctl(fd, KDGKBMODE, &mode) < 0)
+#endif
+	{
 		speed_t ispeed, ospeed;
 		struct winsize ws;
+		errno = 0;
 
 		/* this is a modem line */
 		con->flags |= CON_SERIAL;
@@ -191,9 +200,7 @@ static void tcinit(struct console *con)
 		goto setattr;
 	}
 #if defined(IUTF8) && defined(KDGKBMODE)
-	/* Detect mode of current keyboard setup, e.g. for UTF-8 */
-	if (ioctl(fd, KDGKBMODE, &mode) < 0)
-		mode = K_RAW;
+	/* Handle mode of current keyboard setup, e.g. for UTF-8 */
 	switch(mode) {
 	case K_UNICODE:
 		setlocale(LC_CTYPE, "C.UTF-8");
--- term-utils/agetty.c
+++ term-utils/agetty.c	2014-05-08 08:02:16.786235584 +0000
@@ -139,6 +139,7 @@ struct options {
 	int nice;			/* Run login with this priority */
 	int numspeed;			/* number of baud rates to try */
 	int clocal;			/* CLOCAL_MODE_* */
+	int kbmode;			/* Keyboard mode if virtual console */
 	speed_t speeds[MAX_SPEED];	/* baud rates to be tried */
 };
 
@@ -936,7 +937,7 @@ static void update_utmp(struct options *
 static void open_tty(char *tty, struct termios *tp, struct options *op)
 {
 	const pid_t pid = getpid();
-	int serial, closed = 0;
+	int closed = 0;
 
 	/* Set up new standard input, unless we are given an already opened port. */
 
@@ -1080,15 +1081,18 @@ static void open_tty(char *tty, struct t
 #endif
 	/*
 	 * Detect if this is a virtual console or serial/modem line.
-	 * In case of a virtual console the ioctl TIOCMGET fails and
-	 * the error number will be set to EINVAL.
+	 * In case of a virtual console the ioctl KDGKBMODE succeeds
+	 * whereas on other lines it will fails.
 	 */
-	if (ioctl(STDIN_FILENO, TIOCMGET, &serial) < 0 && (errno == EINVAL)) {
+	if (ioctl(STDIN_FILENO, KDGKBMODE, &op->kbmode) == 0) {
 		op->flags |= F_VCONSOLE;
 		if (!op->term)
 			op->term = DEFAULT_VCTERM;
-	} else if (!op->term)
-		op->term = DEFAULT_STERM;
+	} else {
+		op->kbmode = K_RAW;
+		if (!op->term)
+			op->term = DEFAULT_STERM;
+	}
 
 	setenv("TERM", op->term, 1);
 }
@@ -1122,12 +1126,7 @@ static void termio_init(struct options *
 
 	if (op->flags & F_VCONSOLE) {
 #if defined(IUTF8) && defined(KDGKBMODE)
-		int mode;
-
-		/* Detect mode of current keyboard setup, e.g. for UTF-8 */
-		if (ioctl(STDIN_FILENO, KDGKBMODE, &mode) < 0)
-			mode = K_RAW;
-		switch(mode) {
+		switch(op->kbmode) {
 		case K_UNICODE:
 			setlocale(LC_CTYPE, "C.UTF-8");
 			op->flags |= F_UTF8;