[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_op
From: |
Gerd Hoffmann |
Subject: |
Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd. |
Date: |
Wed, 23 Jul 2008 16:24:23 +0200 |
User-agent: |
Thunderbird 2.0.0.14 (X11/20080501) |
Hi,
> Which means we need our own code for ptys and can't use the generic fd
> functions. I'll go trying cooking up a patch ...
Comments on this one?
cheers,
Gerd
--
http://kraxel.fedorapeople.org/xenner/
diff --git a/vl.c b/vl.c
index 1af6d10..23d92e5 100644
--- a/vl.c
+++ b/vl.c
@@ -2454,21 +2454,153 @@ void cfmakeraw (struct termios *termios_p)
#endif
#if defined(__linux__) || defined(__sun__)
+
+typedef struct {
+ int fd;
+ int connected;
+ int polling;
+ int read_bytes;
+ int interval;
+ QEMUTimer *timer;
+} PtyCharDriver;
+
+static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+ PtyCharDriver *s = chr->opaque;
+ if (!s->connected)
+ return 0;
+ return unix_write(s->fd, buf, len);
+}
+
+static void pty_chr_state(CharDriverState *chr, int connected)
+{
+ PtyCharDriver *s = chr->opaque;
+
+ if (s->connected == connected)
+ return;
+ if (connected) {
+ fprintf(stderr,"%s: %s connected\n", __FUNCTION__, ptsname(s->fd));
+ s->connected = 1;
+ qemu_chr_reset(chr);
+ } else {
+ fprintf(stderr,"%s: %s disconnected\n", __FUNCTION__, ptsname(s->fd));
+ s->connected = 0;
+ qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + s->interval);
+ }
+}
+
+static int pty_chr_read_poll(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ PtyCharDriver *s = chr->opaque;
+
+ s->read_bytes = qemu_chr_can_read(chr);
+ return s->read_bytes;
+}
+
+static void pty_chr_read(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ PtyCharDriver *s = chr->opaque;
+ int size, len;
+ uint8_t buf[1024];
+
+ len = sizeof(buf);
+ if (len > s->read_bytes)
+ len = s->read_bytes;
+ if (len == 0)
+ return;
+ size = read(s->fd, buf, len);
+ if ((size == -1 && EIO == errno) ||
+ (size == 0)) {
+ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ s->polling = 0;
+ pty_chr_state(chr, 0);
+ return;
+ }
+ if (size > 0) {
+ pty_chr_state(chr, 1);
+ qemu_chr_read(chr, buf, size);
+ }
+}
+
+static void pty_chr_update_read_handler(CharDriverState *chr)
+{
+ PtyCharDriver *s = chr->opaque;
+
+ qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
+ pty_chr_read, NULL, chr);
+ s->polling = 1;
+ qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + s->interval);
+}
+
+void pty_chr_timer(void *opaque)
+{
+ struct CharDriverState *chr = opaque;
+ PtyCharDriver *s = chr->opaque;
+
+ if (s->connected) {
+ /* All fine, nothing to do. */
+ return;
+ }
+ if (s->polling) {
+ /* Ran for a while without getting EIO for reads,
+ * probably someone connected to the slave pty. */
+ pty_chr_state(chr, 1);
+ return;
+ }
+ /* Try reading again ... */
+#if 0
+ fprintf(stderr,"%s: %s checking ...\n", __FUNCTION__, ptsname(s->fd));
+#endif
+ pty_chr_update_read_handler(chr);
+}
+
+static void pty_chr_close(struct CharDriverState *chr)
+{
+ PtyCharDriver *s = chr->opaque;
+
+ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ close(s->fd);
+ qemu_free(s);
+}
+
static CharDriverState *qemu_chr_open_pty(void)
{
+ CharDriverState *chr;
+ PtyCharDriver *s;
struct termios tty;
- int master_fd, slave_fd;
+ int slave_fd;
+
+ chr = qemu_mallocz(sizeof(CharDriverState));
+ if (!chr)
+ return NULL;
+ s = qemu_mallocz(sizeof(PtyCharDriver));
+ if (!s) {
+ free(chr);
+ return NULL;
+ }
- if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+ if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
return NULL;
}
/* Set raw attributes on the pty. */
cfmakeraw(&tty);
tcsetattr(slave_fd, TCSAFLUSH, &tty);
+ close(slave_fd);
+
+ fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
+
+ chr->opaque = s;
+ chr->chr_write = pty_chr_write;
+ chr->chr_update_read_handler = pty_chr_update_read_handler;
+ chr->chr_close = pty_chr_close;
- fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
- return qemu_chr_open_fd(master_fd, master_fd);
+ s->interval = 100; /* miliseconds */
+ s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
+
+ return chr;
}
static void tty_serial_init(int fd, int speed,
- [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Ian Jackson, 2008/07/18
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Anthony Liguori, 2008/07/22
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Daniel P. Berrange, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Gerd Hoffmann, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Daniel P. Berrange, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Gerd Hoffmann, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Daniel P. Berrange, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.,
Gerd Hoffmann <=
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Anthony Liguori, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Daniel P. Berrange, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Anthony Liguori, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Gerd Hoffmann, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Anthony Liguori, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Jamie Lokier, 2008/07/23
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Gerd Hoffmann, 2008/07/24
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Gerd Hoffmann, 2008/07/24
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Daniel P. Berrange, 2008/07/24
- Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd., Jamie Lokier, 2008/07/24