From patchwork Tue Feb 5 16:22:15 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 218325 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1ED8E2C02C6 for ; Wed, 6 Feb 2013 06:19:23 +1100 (EST) Received: from localhost ([::1]:38530 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2o37-0006Sk-7b for incoming@patchwork.ozlabs.org; Tue, 05 Feb 2013 14:19:21 -0500 Received: from eggs.gnu.org ([208.118.235.92]:35492) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2o2r-0006PY-Pb for qemu-devel@nongnu.org; Tue, 05 Feb 2013 14:19:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U2lHq-00080z-Dn for qemu-devel@nongnu.org; Tue, 05 Feb 2013 11:22:31 -0500 Received: from oxygen.pond.sub.org ([2a01:4f8:121:10e4::3]:52241) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U2lHq-000804-2W for qemu-devel@nongnu.org; Tue, 05 Feb 2013 11:22:22 -0500 Received: from blackfin.pond.sub.org (p57B0FFFA.dip.t-dialin.net [87.176.255.250]) by oxygen.pond.sub.org (Postfix) with ESMTPA id CA119A43D7; Tue, 5 Feb 2013 17:22:20 +0100 (CET) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C0D69200B5; Tue, 5 Feb 2013 17:22:17 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Tue, 5 Feb 2013 17:22:15 +0100 Message-Id: <1360081335-6594-13-git-send-email-armbru@redhat.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1360081335-6594-1-git-send-email-armbru@redhat.com> References: <1360081335-6594-1-git-send-email-armbru@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:4f8:121:10e4::3 Cc: lilei@linux.vnet.ibm.com, lcapitulino@redhat.com Subject: [Qemu-devel] [PATCH for-1.4 12/12] QAPI QMP HMP: Fix and improve memchar-read/-write docs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org In particular, document the impact of our crappy UTF-8 handling on reading. Now the QMP examples even work. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- hmp-commands.hx | 20 ++++++++------------ qapi-schema.json | 37 +++++++++++++++++++++++-------------- qemu-char.c | 7 +++++++ qmp-commands.hx | 37 +++++++++++++++++++------------------ 4 files changed, 57 insertions(+), 44 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index bdd48f3..ab75b95 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -844,16 +844,15 @@ ETEXI .name = "memchar_write", .args_type = "device:s,data:s", .params = "device data", - .help = "Provide writing interface for CirMemCharDriver. Write" - "'data' to it.", + .help = "Write to a memory character device", .mhandler.cmd = hmp_memchar_write, }, STEXI @item memchar_write @var{device} @var{data} @findex memchar_write -Provide writing interface for CirMemCharDriver. Write @var{data} -to char device 'memory'. +Write @var{data} to memory character device @var{device}. @var{data} +must be an UTF-8 string. ETEXI @@ -861,20 +860,17 @@ ETEXI .name = "memchar_read", .args_type = "device:s,size:i", .params = "device size", - .help = "Provide read interface for CirMemCharDriver. Read from" - "it and return the data with size.", + .help = "Read from a memory character device", .mhandler.cmd = hmp_memchar_read, }, STEXI @item memchar_read @var{device} @findex memchar_read -Provide read interface for CirMemCharDriver. Read from char device -'memory' and return the data. - -@var{size} is the size of data want to read from. Refer to unencoded -size of the raw data, would adjust to the init size of the memchar -if the requested size is larger than it. +Read up to @var{size} bytes from memory character device @var{device}. +Bug: can screw up when the buffer contains invalid UTF-8 sequences, +NUL characters, after the ring buffer lost data, and when reading +stops because the size limit is reached. ETEXI diff --git a/qapi-schema.json b/qapi-schema.json index 6f63791..f34f0a2 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -329,9 +329,9 @@ # # An enumeration of data format. # -# @utf8: The data format is 'utf8'. +# @utf8: Data is UTF-8 encoded (RFC 3629) # -# @base64: The data format is 'base64'. +# @base64: Data is Base64 encoded (RFC 3548) # # Since: 1.4 ## @@ -341,15 +341,18 @@ ## # @memchar-write: # -# Provide writing interface for memchardev. Write data to char -# device 'memory'. +# Write to a memory character device # -# @device: the name of the memory char device. +# @device: the memory character device name. # -# @data: the source data write to memchar. +# @data: data to write # -# @format: #optional the format of the data write to chardev 'memory', -# by default is 'utf8'. +# @format: #optional data encoding (default 'utf8'). +# - base64: data must be base64 encoded text. It's binary +# decoding gets written. +# - utf8: data's UTF-8 encoding is written +# - data itself is always Unicode regardless of format, like +# any other string. # # Returns: Nothing on success # @@ -362,15 +365,21 @@ ## # @memchar-read: # -# Provide read interface for memchardev. Read from the char -# device 'memory' and return the data. +# Read from a memory character device. # -# @device: the name of the memory char device. +# @device: the memory character device name. # -# @size: the size to read in bytes. +# @size: how many bytes to read at most # -# @format: #optional the format of the data want to read from -# memchardev, by default is 'utf8'. +# @format: #optional data encoding (default 'utf8'). +# - base64: the data read is returned in base64 encoding. +# - utf8: the data read is interpreted as UTF-8. +# Bug: can screw up when the buffer contains invalid UTF-8 +# sequences, NUL characters, after the ring buffer lost +# data, and when reading stops because the size limit is +# reached. +# - The return value is always Unicode regardless of format, +# like any other string. # # Returns: data read from the device # diff --git a/qemu-char.c b/qemu-char.c index 3123432..effde37 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2814,6 +2814,13 @@ char *qmp_memchar_read(const char *device, int64_t size, data = g_base64_encode(read_data, count); 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[count] = 0; data = (char *)read_data; } diff --git a/qmp-commands.hx b/qmp-commands.hx index 51ce2e6..4a2b22f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -475,21 +475,19 @@ SQMP memchar-write ------------- -Provide writing interface for CirMemCharDriver. Write data to memory -char device. +Write to a memory character device. Arguments: -- "device": the name of the char device, must be unique (json-string) -- "data": the source data write to memory (json-string) -- "format": the data format write to memory, default is - utf8. (json-string, optional) - - Possible values: "utf8", "base64" +- "device": memory character device name (json-string) +- "data": data to write (json-string) +- "format": data format (json-string, optional) + - Possible values: "utf8" (default), "base64" Example: -> { "execute": "memchar-write", - "arguments": { "device": foo, + "arguments": { "device": "foo", "data": "abcdefgh", "format": "utf8" } } <- { "return": {} } @@ -506,23 +504,26 @@ SQMP memchar-read ------------- -Provide read interface for CirMemCharDriver. Read from the char -device memory and return the data with size. +Read from a memory character device. Arguments: -- "device": the name of the char device, must be unique (json-string) -- "size": the memory size wanted to read in bytes (refer to unencoded - size of the raw data), would adjust to the init size of the - memchar if the requested size is larger than it. (json-int) -- "format": the data format write to memchardev, default is - utf8. (json-string, optional) - - Possible values: "utf8", "base64" +- "device": memory character device name (json-string) +- "size": how many bytes to read at most (json-int) + - Number of data bytes, not number of characters in encoded data +- "format": data format (json-string, optional) + - Possible values: "utf8" (default), "base64" + - Naturally, format "utf8" works only when the ring buffer + contains valid UTF-8 text. Invalid UTF-8 sequences get + replaced. Bug: replacement doesn't work. Bug: can screw + up on encountering NUL characters, after the ring buffer + lost data, and when reading stops because the size limit + is reached. Example: -> { "execute": "memchar-read", - "arguments": { "device": foo, + "arguments": { "device": "foo", "size": 1000, "format": "utf8" } } <- {"return": "abcdefgh"}