summaryrefslogtreecommitdiff
path: root/qemu-char.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu-char.c')
-rw-r--r--qemu-char.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/qemu-char.c b/qemu-char.c
index edc9ad685..ee4f4cab2 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -97,6 +97,7 @@
#endif
#include "qemu_socket.h"
+#include "ui/qemu-spice.h"
#define READ_BUF_LEN 4096
@@ -715,7 +716,7 @@ static void stdio_read(void *opaque)
/* init terminal so that we can grab keys */
static struct termios oldtty;
static int old_fd0_flags;
-static int term_atexit_done;
+static bool stdio_allow_signal;
static void term_exit(void)
{
@@ -723,32 +724,26 @@ static void term_exit(void)
fcntl(0, F_SETFL, old_fd0_flags);
}
-static void term_init(QemuOpts *opts)
+static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
{
struct termios tty;
- tcgetattr (0, &tty);
- oldtty = tty;
- old_fd0_flags = fcntl(0, F_GETFL);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+ tty = oldtty;
+ if (!echo) {
+ tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+ tty.c_oflag |= OPOST;
+ tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+ tty.c_cflag &= ~(CSIZE|PARENB);
+ tty.c_cflag |= CS8;
+ tty.c_cc[VMIN] = 1;
+ tty.c_cc[VTIME] = 0;
+ }
/* if graphical mode, we allow Ctrl-C handling */
- if (!qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC))
+ if (!stdio_allow_signal)
tty.c_lflag &= ~ISIG;
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
tcsetattr (0, TCSANOW, &tty);
-
- if (!term_atexit_done++)
- atexit(term_exit);
-
- fcntl(0, F_SETFL, O_NONBLOCK);
}
static void qemu_chr_close_stdio(struct CharDriverState *chr)
@@ -765,11 +760,21 @@ static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)
if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
return NULL;
+ if (stdio_nb_clients == 0) {
+ old_fd0_flags = fcntl(0, F_GETFL);
+ tcgetattr (0, &oldtty);
+ fcntl(0, F_SETFL, O_NONBLOCK);
+ atexit(term_exit);
+ }
+
chr = qemu_chr_open_fd(0, 1);
chr->chr_close = qemu_chr_close_stdio;
+ chr->chr_set_echo = qemu_chr_set_echo_stdio;
qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
stdio_nb_clients++;
- term_init(opts);
+ stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
+ display_type != DT_NOGRAPHIC);
+ qemu_chr_set_echo(chr, false);
return chr;
}
@@ -1012,9 +1017,6 @@ static void tty_serial_init(int fd, int speed,
speed, parity, data_bits, stop_bits);
#endif
tcgetattr (fd, &tty);
- if (!term_atexit_done) {
- oldtty = tty;
- }
#define check_speed(val) if (speed <= val) { spd = B##val; break; }
speed = speed * 10 / 11;
@@ -1186,11 +1188,6 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
return 0;
}
-static void tty_exit(void)
-{
- tcsetattr(0, TCSANOW, &oldtty);
-}
-
static void qemu_chr_close_tty(CharDriverState *chr)
{
FDCharDriver *s = chr->opaque;
@@ -1225,8 +1222,6 @@ static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
}
chr->chr_ioctl = tty_serial_ioctl;
chr->chr_close = qemu_chr_close_tty;
- if (!term_atexit_done++)
- atexit(tty_exit);
return chr;
}
#else /* ! __linux__ && ! __sun__ */
@@ -2495,6 +2490,9 @@ static const struct {
|| defined(__FreeBSD_kernel__)
{ .name = "parport", .open = qemu_chr_open_pp },
#endif
+#ifdef CONFIG_SPICE
+ { .name = "spicevmc", .open = qemu_chr_open_spice },
+#endif
};
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
@@ -2561,9 +2559,17 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
monitor_init(chr, MONITOR_USE_READLINE);
}
+ qemu_opts_del(opts);
return chr;
}
+void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
+{
+ if (chr->chr_set_echo) {
+ chr->chr_set_echo(chr, echo);
+ }
+}
+
void qemu_chr_close(CharDriverState *chr)
{
QTAILQ_REMOVE(&chardevs, chr, next);