提交 a80bf99f 编写于 作者: A aliguori

char-mux: Use separate input buffers (Jan Kiszka)

Currently, the intermediate input buffer of mux'ed character devices
records data across all sub-devices. This has the side effect that we
easily leak data recorded over one sub-devices to another once we switch
the focus. Avoid data loss and confusion by defining exclusive buffers.

Note: In contrast to the original author's claim, the buffering concept
still breaks down when the fifo of the currently active sub-device is
full. As we cannot accept futher data from this point on without risking
to loose it, we will also miss escape sequences, just like without all
that buffering. In short: There is no reliable escape sequence handling
without infinite buffers or the risk of loosing some data.
Signed-off-by: NJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6701 c046a42c-6fe2-441c-8c8c-71466251a162
上级 2970a6c9
...@@ -225,12 +225,15 @@ typedef struct { ...@@ -225,12 +225,15 @@ typedef struct {
IOEventHandler *chr_event[MAX_MUX]; IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX]; void *ext_opaque[MAX_MUX];
CharDriverState *drv; CharDriverState *drv;
unsigned char buffer[MUX_BUFFER_SIZE];
int prod;
int cons;
int mux_cnt; int mux_cnt;
int term_got_escape; int term_got_escape;
int max_size; int max_size;
/* Intermediate input buffer allows to catch escape sequences even if the
currently active device is not accepting any input - but only until it
is full as well. */
unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
int prod[MAX_MUX];
int cons[MAX_MUX];
} MuxDriver; } MuxDriver;
...@@ -360,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr) ...@@ -360,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr)
int m = chr->focus; int m = chr->focus;
MuxDriver *d = chr->opaque; MuxDriver *d = chr->opaque;
while (d->prod != d->cons && while (d->prod[m] != d->cons[m] &&
d->chr_can_read[m] && d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m])) { d->chr_can_read[m](d->ext_opaque[m])) {
d->chr_read[m](d->ext_opaque[m], d->chr_read[m](d->ext_opaque[m],
&d->buffer[d->cons++ & MUX_BUFFER_MASK], 1); &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
} }
} }
...@@ -372,11 +375,12 @@ static int mux_chr_can_read(void *opaque) ...@@ -372,11 +375,12 @@ static int mux_chr_can_read(void *opaque)
{ {
CharDriverState *chr = opaque; CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque; MuxDriver *d = chr->opaque;
int m = chr->focus;
if ((d->prod - d->cons) < MUX_BUFFER_SIZE) if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
return 1; return 1;
if (d->chr_can_read[chr->focus]) if (d->chr_can_read[m])
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]); return d->chr_can_read[m](d->ext_opaque[m]);
return 0; return 0;
} }
...@@ -391,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) ...@@ -391,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
for(i = 0; i < size; i++) for(i = 0; i < size; i++)
if (mux_proc_byte(chr, d, buf[i])) { if (mux_proc_byte(chr, d, buf[i])) {
if (d->prod == d->cons && if (d->prod[m] == d->cons[m] &&
d->chr_can_read[m] && d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m])) d->chr_can_read[m](d->ext_opaque[m]))
d->chr_read[m](d->ext_opaque[m], &buf[i], 1); d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
else else
d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i]; d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册