diff options
author | Markus Armbruster <armbru@redhat.com> | 2013-02-06 21:27:24 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-02-06 16:35:19 -0600 |
commit | 3949e59414fccefadc50ae65650d676cc734048c (patch) | |
tree | bb6d54b1ce4491ec37c74d06cbf6e4aedefa54a9 /qemu-char.c | |
parent | 5c230105cdea8ac9338bd5b4485c6ae80ec1fa18 (diff) |
qemu-char: Saner naming of memchar stuff & doc fixes
New device, has never been released, so we can still improve things
without worrying about compatibility.
Naming is a mess. The code calls the device driver CirMemCharDriver,
the public API calls it "memory", "memchardev", or "memchar", and the
special commands are named like "memchar-FOO". "memory" is a
particularly unfortunate choice, because there's another character
device driver called MemoryDriver. Moreover, the device's distinctive
property is that it's a ring buffer, not that's in memory. Therefore:
* Rename CirMemCharDriver to RingBufCharDriver, and call the thing a
"ringbuf" in the API.
* Rename QMP and HMP commands from memchar-FOO to ringbuf-FOO.
* Rename device parameter from maxcapacity to size (simple words are
good for you).
* Clearly mark the parameter as optional in documentation.
* Fix error reporting so that chardev-add reports to current monitor,
not stderr.
* Replace cirmem in C identifiers by ringbuf.
* Rework documentation. Document the impact of our crappy UTF-8
handling on reading.
* QMP examples that even work.
I could split this up into multiple commits, but they'd change the
same documentation lines multiple times. Not worth it.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'qemu-char.c')
-rw-r--r-- | qemu-char.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/qemu-char.c b/qemu-char.c index 831d564a8b..8a3540389a 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2645,25 +2645,25 @@ size_t qemu_chr_mem_osize(const CharDriverState *chr) } /*********************************************************/ -/* CircularMemory chardev */ +/* Ring buffer chardev */ typedef struct { size_t size; size_t prod; size_t cons; uint8_t *cbuf; -} CirMemCharDriver; +} RingBufCharDriver; -static size_t cirmem_count(const CharDriverState *chr) +static size_t ringbuf_count(const CharDriverState *chr) { - const CirMemCharDriver *d = chr->opaque; + const RingBufCharDriver *d = chr->opaque; return d->prod - d->cons; } -static int cirmem_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { - CirMemCharDriver *d = chr->opaque; + RingBufCharDriver *d = chr->opaque; int i; if (!buf || (len < 0)) { @@ -2680,9 +2680,9 @@ static int cirmem_chr_write(CharDriverState *chr, const uint8_t *buf, int len) return 0; } -static int cirmem_chr_read(CharDriverState *chr, uint8_t *buf, int len) +static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) { - CirMemCharDriver *d = chr->opaque; + RingBufCharDriver *d = chr->opaque; int i; for (i = 0; i < len && d->cons != d->prod; i++) { @@ -2692,31 +2692,31 @@ static int cirmem_chr_read(CharDriverState *chr, uint8_t *buf, int len) return i; } -static void cirmem_chr_close(struct CharDriverState *chr) +static void ringbuf_chr_close(struct CharDriverState *chr) { - CirMemCharDriver *d = chr->opaque; + RingBufCharDriver *d = chr->opaque; g_free(d->cbuf); g_free(d); chr->opaque = NULL; } -static CharDriverState *qemu_chr_open_cirmemchr(QemuOpts *opts) +static CharDriverState *qemu_chr_open_ringbuf(QemuOpts *opts) { CharDriverState *chr; - CirMemCharDriver *d; + RingBufCharDriver *d; chr = g_malloc0(sizeof(CharDriverState)); d = g_malloc(sizeof(*d)); - d->size = qemu_opt_get_number(opts, "maxcapacity", 0); + d->size = qemu_opt_get_number(opts, "size", 0); if (d->size == 0) { d->size = CBUFF_SIZE; } /* The size must be power of 2 */ if (d->size & (d->size - 1)) { - fprintf(stderr, "chardev: size of memory device must be power of 2\n"); + error_report("size of ringbuf device must be power of two"); goto fail; } @@ -2725,8 +2725,8 @@ static CharDriverState *qemu_chr_open_cirmemchr(QemuOpts *opts) d->cbuf = g_malloc0(d->size); chr->opaque = d; - chr->chr_write = cirmem_chr_write; - chr->chr_close = cirmem_chr_close; + chr->chr_write = ringbuf_chr_write; + chr->chr_close = ringbuf_chr_close; return chr; @@ -2736,12 +2736,12 @@ fail: return NULL; } -static bool chr_is_cirmem(const CharDriverState *chr) +static bool chr_is_ringbuf(const CharDriverState *chr) { - return chr->chr_write == cirmem_chr_write; + return chr->chr_write == ringbuf_chr_write; } -void qmp_memchar_write(const char *device, const char *data, +void qmp_ringbuf_write(const char *device, const char *data, bool has_format, enum DataFormat format, Error **errp) { @@ -2756,8 +2756,8 @@ void qmp_memchar_write(const char *device, const char *data, return; } - if (!chr_is_cirmem(chr)) { - error_setg(errp,"%s is not memory char device", device); + if (!chr_is_ringbuf(chr)) { + error_setg(errp,"%s is not a ringbuf device", device); return; } @@ -2768,7 +2768,7 @@ void qmp_memchar_write(const char *device, const char *data, write_count = strlen(data); } - ret = cirmem_chr_write(chr, write_data, write_count); + ret = ringbuf_chr_write(chr, write_data, write_count); if (write_data != (uint8_t *)data) { g_free((void *)write_data); @@ -2780,7 +2780,7 @@ void qmp_memchar_write(const char *device, const char *data, } } -char *qmp_memchar_read(const char *device, int64_t size, +char *qmp_ringbuf_read(const char *device, int64_t size, bool has_format, enum DataFormat format, Error **errp) { @@ -2795,8 +2795,8 @@ char *qmp_memchar_read(const char *device, int64_t size, return NULL; } - if (!chr_is_cirmem(chr)) { - error_setg(errp,"%s is not memory char device", device); + if (!chr_is_ringbuf(chr)) { + error_setg(errp,"%s is not a ringbuf device", device); return NULL; } @@ -2805,16 +2805,23 @@ char *qmp_memchar_read(const char *device, int64_t size, return NULL; } - count = cirmem_count(chr); + count = ringbuf_count(chr); size = size > count ? count : size; read_data = g_malloc(size + 1); - cirmem_chr_read(chr, read_data, size); + ringbuf_chr_read(chr, read_data, size); if (has_format && (format == DATA_FORMAT_BASE64)) { data = g_base64_encode(read_data, size); g_free(read_data); } else { + /* + * FIXME should read only complete, valid UTF-8 characters up + * to @size bytes. Invalid sequences should be replaced by a + * suitable replacement character. Except when (and only + * when) ring buffer lost characters since last read, initial + * continuation characters should be dropped. + */ read_data[size] = 0; data = (char *)read_data; } @@ -2975,7 +2982,7 @@ static const struct { { .name = "udp", .open = qemu_chr_open_udp }, { .name = "msmouse", .open = qemu_chr_open_msmouse }, { .name = "vc", .open = text_console_init }, - { .name = "memory", .open = qemu_chr_open_cirmemchr }, + { .name = "memory", .open = qemu_chr_open_ringbuf }, #ifdef _WIN32 { .name = "file", .open = qemu_chr_open_win_file_out }, { .name = "pipe", .open = qemu_chr_open_win_pipe }, @@ -3236,7 +3243,7 @@ QemuOptsList qemu_chardev_opts = { .name = "debug", .type = QEMU_OPT_NUMBER, },{ - .name = "maxcapacity", + .name = "size", .type = QEMU_OPT_NUMBER, }, { /* end of list */ } |