From 3af59d5e0049aef93a0f3a4b38ff6e0f160f42df Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Jun 2014 20:47:54 +0100 Subject: qemu-char: Convert socket char backend to parse/kind Convert the socket char backend to the new style QAPI framework; this allows it to return an Error ** to callers who might not want it to print directly about socket failures. [The rationale for this patch from the ranchu perspective is that it means that if our attempt to create the android console backend chardev fails because the port was in use we don't get a spurious warning printed to stderr.] Signed-off-by: Peter Maydell --- qemu-char.c | 113 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index b6430c7428..ca9b160034 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2723,61 +2723,6 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, return chr; } -static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) -{ - CharDriverState *chr = NULL; - Error *local_err = NULL; - int fd = -1; - - bool is_listen = qemu_opt_get_bool(opts, "server", false); - bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); - bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); - bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); - bool is_unix = qemu_opt_get(opts, "path") != NULL; - - if (is_unix) { - if (is_listen) { - fd = unix_listen_opts(opts, &local_err); - } else { - fd = unix_connect_opts(opts, &local_err, NULL, NULL); - } - } else { - if (is_listen) { - fd = inet_listen_opts(opts, 0, &local_err); - } else { - fd = inet_connect_opts(opts, &local_err, NULL, NULL); - } - } - if (fd < 0) { - goto fail; - } - - if (!is_waitconnect) - qemu_set_nonblock(fd); - - chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet, - is_waitconnect, &local_err); - if (local_err) { - goto fail; - } - return chr; - - - fail: - if (local_err) { - qerror_report_err(local_err); - error_free(local_err); - } - if (fd >= 0) { - closesocket(fd); - } - if (chr) { - g_free(chr->opaque); - g_free(chr); - } - return NULL; -} - /*********************************************************/ /* Ring buffer chardev */ @@ -3184,6 +3129,61 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, backend->mux->chardev = g_strdup(chardev); } +static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + bool is_listen = qemu_opt_get_bool(opts, "server", false); + bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); + bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); + bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); + const char *path = qemu_opt_get(opts, "path"); + const char *host = qemu_opt_get(opts, "host"); + const char *port = qemu_opt_get(opts, "port"); + SocketAddress *addr; + + if (!path) { + if (!host) { + error_setg(errp, "chardev: socket: no host given"); + return; + } + if (!port) { + error_setg(errp, "chardev: socket: no port given"); + return; + } + } + + backend->socket = g_new0(ChardevSocket, 1); + + backend->socket->has_nodelay = true; + backend->socket->nodelay = do_nodelay; + backend->socket->has_server = true; + backend->socket->server = is_listen; + backend->socket->has_telnet = true; + backend->socket->telnet = is_telnet; + backend->socket->has_wait = true; + backend->socket->wait = is_waitconnect; + + addr = g_new0(SocketAddress, 1); + if (path) { + addr->kind = SOCKET_ADDRESS_KIND_UNIX; + addr->q_unix->path = g_strdup(path); + } else { + addr->kind = SOCKET_ADDRESS_KIND_INET; + addr->inet = g_new0(InetSocketAddress, 1); + addr->inet->host = g_strdup(host); + addr->inet->port = g_strdup(port); + addr->inet->to = qemu_opt_get_number(opts, "to", 0); + addr->inet->has_to = true; + if (qemu_opt_get_bool(opts, "ipv4", 0)) { + addr->inet->has_ipv4 = addr->inet->ipv4 = true; + } + if (qemu_opt_get_bool(opts, "ipv6", 0)) { + addr->inet->has_ipv6 = addr->inet->ipv6 = true; + } + } + backend->socket->addr = addr; +} + typedef struct CharDriver { const char *name; /* old, pre qapi */ @@ -3864,7 +3864,8 @@ void qmp_chardev_remove(const char *id, Error **errp) static void register_types(void) { register_char_driver_qapi("null", CHARDEV_BACKEND_KIND_NULL, NULL); - register_char_driver("socket", qemu_chr_open_socket); + register_char_driver_qapi("socket", CHARDEV_BACKEND_KIND_SOCKET, + qemu_chr_parse_socket); register_char_driver("udp", qemu_chr_open_udp); register_char_driver_qapi("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf); -- cgit v1.2.3