From patchwork Fri Jan 31 17:34:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonios Motakis X-Patchwork-Id: 315795 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 010D22C00AE for ; Sat, 1 Feb 2014 04:36:06 +1100 (EST) Received: from localhost ([::1]:57271 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W9I0Z-0002BB-HU for incoming@patchwork.ozlabs.org; Fri, 31 Jan 2014 12:36:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32799) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W9Hzg-0000fq-OC for qemu-devel@nongnu.org; Fri, 31 Jan 2014 12:35:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W9Hza-0003KU-2f for qemu-devel@nongnu.org; Fri, 31 Jan 2014 12:35:08 -0500 Received: from mail-wg0-f44.google.com ([74.125.82.44]:60632) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W9HzZ-0003KK-Qv for qemu-devel@nongnu.org; Fri, 31 Jan 2014 12:35:02 -0500 Received: by mail-wg0-f44.google.com with SMTP id l18so9285380wgh.23 for ; Fri, 31 Jan 2014 09:35:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QXWELYFsCxGsJerfporLk3Gn8BfDQHKIVkoN3EQCtLs=; b=BUDayJLRuUadu0EO92AbIU8AtSQrLF982zqLZYnRcIwu9qYAxanM7zyV1SAsx1nmoy KOO42k0KqJafA0EMjj6wErbLKfzUE58C/bY/nQVwMIQpd/SrE9CjvG7ahjJ+NvG3tKtO NiX+dZ0phaM4MvlomV5oi7KHQHxsWG1UTevLZseRH8q1HnkhcfgpUkfthwv1yVYiWj9i pgsW/g5dLezKuQhjHof410UQPl/nOq4biVNKJpMaJ8x1/34XCZ+2ET5qtdVHnjfxmkb1 0MJRN9yE5QB/oql1ZHwafNxGNZycobjdkUU/CqrnhfINY2RxLoRH3Zrz9Q/NA0M+OGy/ Za1w== X-Gm-Message-State: ALoCoQm59GHbxwzidVwdlUzLFceKtJSe85vCflXyppN3YybTBq/Xj1EoKV83pk3PQbmjF25nCdlX X-Received: by 10.180.221.38 with SMTP id qb6mr14537421wic.26.1391189701061; Fri, 31 Jan 2014 09:35:01 -0800 (PST) Received: from localhost.localdomain (home.tvelocity.eu. [82.67.68.96]) by mx.google.com with ESMTPSA id cm5sm21309470wid.5.2014.01.31.09.34.58 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 31 Jan 2014 09:35:00 -0800 (PST) From: Antonios Motakis To: qemu-devel@nongnu.org, snabb-devel@googlegroups.com Date: Fri, 31 Jan 2014 18:34:31 +0100 Message-Id: <1391189683-1602-3-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1391189683-1602-1-git-send-email-a.motakis@virtualopensystems.com> References: <1391189683-1602-1-git-send-email-a.motakis@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.44 Cc: mst@redhat.com, Amit Shah , Michael Roth , n.nikolaev@virtualopensystems.com, Hans de Goede , Gerd Hoffmann , Anthony Liguori , lukego@gmail.com, Antonios Motakis , tech@virtualopensystems.com Subject: [Qemu-devel] [PATCH v7 02/13] Add chardev API qemu_chr_fe_read_all 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 This function will attempt to read data from the chardev trying to fill the buffer up to the given length. Signed-off-by: Antonios Motakis Signed-off-by: Nikolay Nikolaev --- include/sysemu/char.h | 14 +++++++++++ qemu-char.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b81a6ff..9981a6a 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -56,6 +56,8 @@ typedef void IOEventHandler(void *opaque, int event); struct CharDriverState { void (*init)(struct CharDriverState *s); int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); + int (*chr_sync_read)(struct CharDriverState *s, + const uint8_t *buf, int len); GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); void (*chr_update_read_handler)(struct CharDriverState *s); int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); @@ -189,6 +191,18 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); /** + * @qemu_chr_fe_read_all: + * + * Read data to a buffer from the back end. + * + * @buf the data buffer + * @len the number of bytes to read + * + * Returns: the number of bytes read + */ +int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len); + +/** * @qemu_chr_fe_ioctl: * * Issue a device specific ioctl to a backend. diff --git a/qemu-char.c b/qemu-char.c index 30c5a6a..54ac03c 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -84,6 +84,7 @@ #include "ui/qemu-spice.h" #define READ_BUF_LEN 4096 +#define READ_RETRIES 10 /***********************************************************/ /* character device */ @@ -145,6 +146,41 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) return offset; } +int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len) +{ + int offset = 0, counter = 10; + int res; + + if (!s->chr_sync_read) { + return 0; + } + + while (offset < len) { + do { + res = s->chr_sync_read(s, buf + offset, len - offset); + if (res == -1 && errno == EAGAIN) { + g_usleep(100); + } + } while (res == -1 && errno == EAGAIN); + + if (res == 0) { + break; + } + + if (res < 0) { + return res; + } + + offset += res; + + if (!counter--) { + break; + } + } + + return offset; +} + int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) { if (!s->chr_ioctl) @@ -2489,6 +2525,34 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) return TRUE; } +static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) +{ + TCPCharDriver *s = chr->opaque; + int size; + + if (!s->connected) { + return 0; + } + + size = tcp_chr_recv(chr, (void *) buf, len); + if (size == 0) { + /* connection closed */ + s->connected = 0; + if (s->listen_chan) { + s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, + tcp_chr_accept, chr); + } + remove_fd_in_watch(chr); + g_io_channel_unref(s->chan); + s->chan = NULL; + closesocket(s->fd); + s->fd = -1; + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + } + + return size; +} + #ifndef _WIN32 CharDriverState *qemu_chr_open_eventfd(int eventfd) { @@ -2660,6 +2724,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, chr->opaque = s; chr->chr_write = tcp_chr_write; + chr->chr_sync_read = tcp_chr_sync_read; chr->chr_close = tcp_chr_close; chr->get_msgfd = tcp_get_msgfd; chr->chr_add_client = tcp_chr_add_client;