From patchwork Tue May 5 22:22:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 468509 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 4DA3714076B for ; Wed, 6 May 2015 08:23:47 +1000 (AEST) Received: from localhost ([::1]:41808 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YplFh-0000m8-8X for incoming@patchwork.ozlabs.org; Tue, 05 May 2015 18:23:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47035) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YplF2-00083g-Ko for qemu-devel@nongnu.org; Tue, 05 May 2015 18:23:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YplEz-0000Ph-K4 for qemu-devel@nongnu.org; Tue, 05 May 2015 18:23:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51968) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YplEz-0000PW-Db for qemu-devel@nongnu.org; Tue, 05 May 2015 18:23:01 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t45MN0WD003711 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 5 May 2015 18:23:00 -0400 Received: from scv.usersys.redhat.com (dhcp-10-18-17-29.lax.redhat.com [10.18.17.29]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t45MMxld015727; Tue, 5 May 2015 18:23:00 -0400 From: John Snow To: qemu-devel@nongnu.org Date: Tue, 5 May 2015 18:22:54 -0400 Message-Id: <1430864578-22072-2-git-send-email-jsnow@redhat.com> In-Reply-To: <1430864578-22072-1-git-send-email-jsnow@redhat.com> References: <1430864578-22072-1-git-send-email-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: pbonzini@redhat.com, John Snow , afaerber@suse.de Subject: [Qemu-devel] [PATCH v3 1/5] qtest: allow arbitrarily long sends 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 qtest currently has a static buffer of size 1024 that if we overflow, ignores the additional data silently which leads to hangs or stream failures. Use glib's string facilities to allow arbitrarily long data, but split this off into a new function, qtest_sendf. Static data can still be sent using qtest_send, which avoids the malloc/copy overflow. Signed-off-by: John Snow Reviewed-by: Eric Blake --- qtest.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/qtest.c b/qtest.c index 8d1e66c..f635a48 100644 --- a/qtest.c +++ b/qtest.c @@ -182,21 +182,29 @@ static void qtest_send_prefix(CharDriverState *chr) (long) tv.tv_sec, (long) tv.tv_usec); } -static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, - const char *fmt, ...) +static void do_qtest_send(CharDriverState *chr, const char *str, size_t len) +{ + qemu_chr_fe_write_all(chr, (uint8_t *)str, len); + if (qtest_log_fp && qtest_opened) { + fprintf(qtest_log_fp, "%s", str); + } +} + +static void qtest_send(CharDriverState *chr, const char *str) +{ + do_qtest_send(chr, str, strlen(str)); +} + +static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharDriverState *chr, + const char *fmt, ...) { va_list ap; - char buffer[1024]; - size_t len; + gchar *buffer; va_start(ap, fmt); - len = vsnprintf(buffer, sizeof(buffer), fmt, ap); + buffer = g_strdup_vprintf(fmt, ap); + qtest_send(chr, buffer); va_end(ap); - - qemu_chr_fe_write_all(chr, (uint8_t *)buffer, len); - if (qtest_log_fp && qtest_opened) { - fprintf(qtest_log_fp, "%s", buffer); - } } static void qtest_irq_handler(void *opaque, int n, int level) @@ -208,8 +216,8 @@ static void qtest_irq_handler(void *opaque, int n, int level) CharDriverState *chr = qtest_chr; irq_levels[n] = level; qtest_send_prefix(chr); - qtest_send(chr, "IRQ %s %d\n", - level ? "raise" : "lower", n); + qtest_sendf(chr, "IRQ %s %d\n", + level ? "raise" : "lower", n); } } @@ -318,7 +326,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) value = cpu_inl(addr); } qtest_send_prefix(chr); - qtest_send(chr, "OK 0x%04x\n", value); + qtest_sendf(chr, "OK 0x%04x\n", value); } else if (strcmp(words[0], "writeb") == 0 || strcmp(words[0], "writew") == 0 || strcmp(words[0], "writel") == 0 || @@ -375,7 +383,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) tswap64s(&value); } qtest_send_prefix(chr); - qtest_send(chr, "OK 0x%016" PRIx64 "\n", value); + qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value); } else if (strcmp(words[0], "read") == 0) { uint64_t addr, len, i; uint8_t *data; @@ -390,7 +398,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) qtest_send_prefix(chr); qtest_send(chr, "OK 0x"); for (i = 0; i < len; i++) { - qtest_send(chr, "%02x", data[i]); + qtest_sendf(chr, "%02x", data[i]); } qtest_send(chr, "\n"); @@ -434,7 +442,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) } qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns); qtest_send_prefix(chr); - qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + qtest_sendf(chr, "OK %"PRIi64"\n", + (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) { int64_t ns; @@ -442,10 +451,11 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) ns = strtoll(words[1], NULL, 0); qtest_clock_warp(ns); qtest_send_prefix(chr); - qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + qtest_sendf(chr, "OK %"PRIi64"\n", + (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); } else { qtest_send_prefix(chr); - qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]); + qtest_sendf(chr, "FAIL Unknown command `%s'\n", words[0]); } }