--- /dev/null
+#ifndef KVM__TERM_H
+#define KVM__TERM_H
+
+#include <sys/uio.h>
+
+#define CONSOLE_8250 1
+#define CONSOLE_VIRTIO 2
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt);
+int term_getc_iov(int who, struct iovec *iov, int iovcnt);
+int term_putc(int who, char *addr, int cnt);
+int term_getc(int who);
+
+bool term_readable(int who);
+void term_init(void);
+
+#endif /* KVM__TERM_H */
#include "kvm/disk-image.h"
#include "kvm/util.h"
#include "kvm/pci.h"
+#include "kvm/term.h"
#include <inttypes.h>
-#include <termios.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
static struct kvm *kvm;
-static struct termios orig_term;
-
-static void setup_console(void)
-{
- struct termios term;
-
- if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
- die("unable to save initial standard input settings");
-
- term = orig_term;
-
- term.c_lflag &= ~(ICANON|ECHO);
-
- tcsetattr(STDIN_FILENO, TCSANOW, &term);
-}
-
-static void cleanup_console(void)
-{
- tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
-}
-
-static void shutdown(void)
-{
- cleanup_console();
-}
-
static void handle_sigint(int sig)
{
exit(1);
kvm__show_registers(kvm);
kvm__show_code(kvm);
kvm__show_page_tables(kvm);
-
kvm__delete(kvm);
exit(1);
signal(SIGQUIT, handle_sigquit);
signal(SIGINT, handle_sigint);
- setup_console();
-
- atexit(shutdown);
-
for (i = 1; i < argc; i++) {
if (option_matches(argv[i], "--kernel=")) {
kernel_filename = &argv[i][9];
if (!kernel_filename)
usage(argv);
+ term_init();
+
kvm = kvm__init(kvm_dev, ram_size);
if (image_filename) {
--- /dev/null
+#include <poll.h>
+#include <stdbool.h>
+#include <termios.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#include "kvm/read-write.h"
+#include "kvm/term.h"
+#include "kvm/util.h"
+
+static struct termios orig_term;
+
+int active_console = CONSOLE_8250;
+
+int term_getc(int who)
+{
+ int c;
+
+ if (who != active_console)
+ return -1;
+
+ if (read_in_full(STDIN_FILENO, &c, 1) < 0)
+ return -1;
+ return c;
+}
+
+int term_putc(int who, char *addr, int cnt)
+{
+ if (who != active_console)
+ return -1;
+
+ while (cnt--) {
+ fprintf(stdout, "%c", *addr++);
+ }
+
+ fflush(stdout);
+ return cnt;
+}
+
+int term_getc_iov(int who, struct iovec *iov, int iovcnt)
+{
+ if (who != active_console)
+ return -1;
+
+ return readv(STDIN_FILENO, iov, iovcnt);
+}
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt)
+{
+ if (who != active_console)
+ return -1;
+
+ return writev(STDOUT_FILENO, iov, iovcnt);
+}
+
+bool term_readable(int who)
+{
+ struct pollfd pollfd = (struct pollfd) {
+ .fd = STDIN_FILENO,
+ .events = POLLIN,
+ .revents = 0,
+ };
+
+ if (who != active_console)
+ return false;
+
+ return poll(&pollfd, 1, 0) > 0;
+}
+
+static void term_cleanup(void)
+{
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+}
+
+void term_init(void)
+{
+ struct termios term;
+
+ if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
+ die("unable to save initial standard input settings");
+
+ term = orig_term;
+ term.c_lflag &= ~(ICANON |ECHO | ISIG);
+ tcsetattr(STDIN_FILENO, TCSANOW, &term);
+
+ atexit(term_cleanup);
+}