]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Put terminal in canonical mode
authorPekka Enberg <penberg@kernel.org>
Sun, 9 Jan 2011 20:15:04 +0000 (22:15 +0200)
committerPekka Enberg <penberg@kernel.org>
Sun, 9 Jan 2011 20:15:04 +0000 (22:15 +0200)
As suggested by Ingo Molnar, put terminal in canonical mode. This makes poll()
on stdin to react to keystrokes insted of return key and fixes the double
echo'd character problem for input.

Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/main.c

index 599df7191dc1c39b732795fbecf0bd0372669573..650f225dfef7efa6994d2563c4d075a6251f50ef 100644 (file)
@@ -7,6 +7,8 @@
 #include "kvm/pci.h"
 
 #include <inttypes.h>
+#include <termios.h>
+#include <unistd.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -28,6 +30,30 @@ static void usage(char *argv[])
 
 static struct kvm *kvm;
 
+static void tty_set_canon_flag(int fd, int on)
+{
+       struct termios tty;
+       int mask = ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF | ICANON | ECHO;
+
+       tcgetattr(fd, &tty);
+       if (on)
+               tty.c_lflag |= mask;
+       else
+               tty.c_lflag &= ~mask;
+       tcsetattr(fd, TCSAFLUSH, &tty);
+}
+
+static void shutdown(void)
+{
+       tty_set_canon_flag(fileno(stdin), 0);
+}
+
+static void handle_sigint(int sig)
+{
+       shutdown();
+       exit(1);
+}
+
 static void handle_sigquit(int sig)
 {
        kvm__show_registers(kvm);
@@ -86,7 +112,6 @@ static void setup_timer(void)
                die("timer_settime()");
 }
 
-
 int main(int argc, char *argv[])
 {
        const char *kernel_filename = NULL;
@@ -98,7 +123,10 @@ int main(int argc, char *argv[])
        bool single_step = false;
        int i;
 
+       atexit(shutdown);
+
        signal(SIGQUIT, handle_sigquit);
+       signal(SIGINT, handle_sigint);
 
        for (i = 1; i < argc; i++) {
                if (option_matches(argv[i], "--kernel=")) {
@@ -175,6 +203,8 @@ int main(int argc, char *argv[])
 
        setup_timer();
 
+       tty_set_canon_flag(fileno(stdin), 1);
+
        for (;;) {
                kvm__run(kvm);