From: Laszlo Ersek Date: Tue, 16 Jul 2013 18:19:40 +0000 (+0200) Subject: char: io_channel_send: don't lose written bytes X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~524^2~3^2~419 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ac8c26f633b01bb32cdf347f9dbd5a80c6712925;p=sdk%2Femulator%2Fqemu.git char: io_channel_send: don't lose written bytes The g_io_channel_write_chars() documentation states, bytes_written: The number of bytes written. This can be nonzero even if the return value is not G_IO_STATUS_NORMAL. [...] io_channel_send() could lose such bytes before. Furthermore, the (status == G_IO_STATUS_EOF) condition used to evaluate to constant false whenever it was reached. When that condition actually held, it always led to -1 / EINVAL. This patch (almost) distinguishes G_IO_STATUS_EOF only when no bytes have been written, and then treats it as an error. Signed-off-by: Laszlo Ersek Reviewed-by: Amit Shah Reviewed-by: Anthony Liguori Message-id: 1373998781-29561-2-git-send-email-lersek@redhat.com Signed-off-by: Anthony Liguori --- diff --git a/qemu-char.c b/qemu-char.c index 800d6a62f9..c86ce4ba2e 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -720,35 +720,32 @@ static GIOChannel *io_channel_from_socket(int fd) static int io_channel_send(GIOChannel *fd, const void *buf, size_t len) { - GIOStatus status; - size_t offset; + size_t offset = 0; + GIOStatus status = G_IO_STATUS_NORMAL; - offset = 0; - while (offset < len) { - gsize bytes_written; + while (offset < len && status == G_IO_STATUS_NORMAL) { + gsize bytes_written = 0; status = g_io_channel_write_chars(fd, buf + offset, len - offset, &bytes_written, NULL); - if (status != G_IO_STATUS_NORMAL) { - if (status == G_IO_STATUS_AGAIN) { - /* If we've written any data, return a partial write. */ - if (offset) { - break; - } - errno = EAGAIN; - } else { - errno = EINVAL; - } - - return -1; - } else if (status == G_IO_STATUS_EOF) { - break; - } - offset += bytes_written; } - return offset; + if (offset > 0) { + return offset; + } + switch (status) { + case G_IO_STATUS_NORMAL: + g_assert(len == 0); + return 0; + case G_IO_STATUS_AGAIN: + errno = EAGAIN; + return -1; + default: + break; + } + errno = EINVAL; + return -1; } #ifndef _WIN32