aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-20 20:47:54 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-06-20 21:43:04 +0100
commit3af59d5e0049aef93a0f3a4b38ff6e0f160f42df (patch)
treeaa1b31eeb5a1d50a2d2cc41188ebfb8c3c3719f9
parenta23f98afa9a028cbf50c53b659229886faf3fc0e (diff)
qemu-char: Convert socket char backend to parse/kindranchu-adb
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 <peter.maydell@linaro.org>
-rw-r--r--qemu-char.c113
1 files 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);