From patchwork Fri Oct 16 08:50:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 531158 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 B23B71402B4 for ; Fri, 16 Oct 2015 20:23:38 +1100 (AEDT) Received: from localhost ([::1]:52065 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zn1Ee-0001kt-2O for incoming@patchwork.ozlabs.org; Fri, 16 Oct 2015 05:23:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50720) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zn0jN-0004oD-9G for qemu-devel@nongnu.org; Fri, 16 Oct 2015 04:51:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zn0jM-0007PF-36 for qemu-devel@nongnu.org; Fri, 16 Oct 2015 04:51:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36580) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zn0jL-0007P1-LO for qemu-devel@nongnu.org; Fri, 16 Oct 2015 04:51:15 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 4A192C0B64AA for ; Fri, 16 Oct 2015 08:51:15 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-80.ams2.redhat.com [10.36.112.80]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9G8oCax010200 for ; Fri, 16 Oct 2015 04:51:14 -0400 From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 16 Oct 2015 10:50:00 +0200 Message-Id: <1444985411-17803-39-git-send-email-pbonzini@redhat.com> In-Reply-To: <1444985411-17803-1-git-send-email-pbonzini@redhat.com> References: <1444985411-17803-1-git-send-email-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 38/49] qemu-char: convert stdio backend to data-driven creation 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 The backend now always returns errors via the Error* argument. This avoids a double error message. Before: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize qemu-system-x86_64: -chardev stdio,id=base: Failed to create chardev After: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 57 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 3ccea3f..2b24a5c 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1168,19 +1168,23 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) fd_chr_close(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevStdio *opts = backend->stdio; CharDriverState *chr; struct sigaction act; if (is_daemonized()) { - error_report("cannot use stdio with -daemonize"); + error_setg(errp, "cannot use stdio with -daemonize"); return NULL; } if (stdio_in_use) { - error_report("cannot use stdio by multiple character devices"); - exit(1); + error_setg(errp, "cannot use stdio by multiple character devices"); + return NULL; } stdio_in_use = true; @@ -2341,7 +2345,10 @@ static void win_stdio_close(CharDriverState *chr) g_free(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; WinStdioCharState *stdio; @@ -2353,8 +2360,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (stdio->hStdIn == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot open stdio: invalid handle\n"); - exit(1); + error_setg(errp, "cannot open stdio: invalid handle"); + return NULL; } is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; @@ -2366,25 +2373,30 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) if (is_console) { if (qemu_add_wait_object(stdio->hStdIn, win_stdio_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err1; } } else { DWORD dwId; stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, - chr, 0, &dwId); - - if (stdio->hInputThread == INVALID_HANDLE_VALUE - || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE + if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot create stdio thread or event\n"); - exit(1); + error_setg(errp, "cannot create event"); + goto err2; } if (qemu_add_wait_object(stdio->hInputReadyEvent, win_stdio_thread_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err2; + } + stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, + chr, 0, &dwId); + + if (stdio->hInputThread == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot create stdio thread"); + goto err3; } } @@ -2402,6 +2414,15 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) qemu_chr_fe_set_echo(chr, false); return chr; + +err3: + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); +err2: + CloseHandle(stdio->hInputReadyEvent); + CloseHandle(stdio->hInputDoneEvent); +err1: + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return NULL; } #endif /* !_WIN32 */ @@ -4330,7 +4351,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_STDIO: - chr = qemu_chr_open_stdio(backend->stdio); + abort(); break; #ifdef _WIN32 case CHARDEV_BACKEND_KIND_CONSOLE: @@ -4420,7 +4441,7 @@ static void register_types(void) register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio, NULL); + qemu_chr_parse_stdio, qemu_chr_open_stdio); #if defined HAVE_CHARDEV_SERIAL register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial);