aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2006-03-30 11:55:07 +0100
committeremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>2006-03-30 11:55:07 +0100
commitecaa88857fb956e33772ae053dd51d2a6a285085 (patch)
tree6d9f7f0df2be9599fcb575bb57eac670c708ddd8
parent51260a849cd9d952e20ba2a2094427aad8bffbfd (diff)
parent5707afc46f6d7e98ee2e06ff11c45e6b1192d4cc (diff)
downloadxen-ecaa88857fb956e33772ae053dd51d2a6a285085.tar.gz
xen-ecaa88857fb956e33772ae053dd51d2a6a285085.tar.bz2
xen-ecaa88857fb956e33772ae053dd51d2a6a285085.zip
Merged.
-rw-r--r--tools/console/daemon/io.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 8b187e5e82..deea3ef6ec 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -434,26 +434,37 @@ void enum_domains(void)
}
}
-static void handle_tty_read(struct domain *dom)
+static int ring_free_bytes(struct domain *dom)
{
- ssize_t len = 0;
- char msg[80];
- int i;
struct xencons_interface *intf = dom->interface;
- XENCONS_RING_IDX cons, prod;
+ XENCONS_RING_IDX cons, prod, space;
cons = intf->in_cons;
prod = intf->in_prod;
mb();
- if (sizeof(intf->in) > (prod - cons))
- len = sizeof(intf->in) - (prod - cons);
- if (len > sizeof(msg))
- len = sizeof(msg);
+ space = prod - cons;
+ if (space > sizeof(intf->in))
+ return 0; /* ring is screwed: ignore it */
+
+ return (sizeof(intf->in) - space);
+}
+
+static void handle_tty_read(struct domain *dom)
+{
+ ssize_t len = 0;
+ char msg[80];
+ int i;
+ struct xencons_interface *intf = dom->interface;
+ XENCONS_RING_IDX prod;
+ len = ring_free_bytes(dom);
if (len == 0)
return;
+ if (len > sizeof(msg))
+ len = sizeof(msg);
+
len = read(dom->tty_fd, msg, len);
if (len < 1) {
close(dom->tty_fd);
@@ -465,6 +476,7 @@ static void handle_tty_read(struct domain *dom)
shutdown_domain(dom);
}
} else if (domain_is_valid(dom->domid)) {
+ prod = intf->in_prod;
for (i = 0; i < len; i++) {
intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
msg[i];
@@ -514,7 +526,7 @@ static void handle_ring_read(struct domain *dom)
(void)write_sync(dom->evtchn_fd, &v, sizeof(v));
}
-static void handle_xs(int fd)
+static void handle_xs(void)
{
char **vec;
int domid;
@@ -560,7 +572,7 @@ void handle_io(void)
}
if (d->tty_fd != -1) {
- if (!d->is_dead)
+ if (!d->is_dead && ring_free_bytes(d))
FD_SET(d->tty_fd, &readfds);
if (!buffer_empty(&d->buffer))
@@ -572,7 +584,7 @@ void handle_io(void)
ret = select(max_fd + 1, &readfds, &writefds, 0, NULL);
if (FD_ISSET(xs_fileno(xs), &readfds))
- handle_xs(xs_fileno(xs));
+ handle_xs();
for (d = dom_head; d; d = n) {
n = d->next;