summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/char.h2
-rw-r--r--qapi-schema.json7
-rw-r--r--qemu-char.c45
-rw-r--r--qemu-doc.texi2
-rw-r--r--util/qemu-sockets.c9
5 files changed, 42 insertions, 23 deletions
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 066c2161d5..e65e4a4844 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -281,7 +281,7 @@ CharDriverState *qemu_chr_find(const char *name);
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
-void register_char_driver_qapi(const char *name, int kind,
+void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
/* add an eventfd to the qemu devices that are polled */
diff --git a/qapi-schema.json b/qapi-schema.json
index 6590307812..5c32528a1c 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3288,10 +3288,11 @@
# @addr: socket address to listen on (server=true)
# or connect to (server=false)
# @server: #optional create server socket (default: true)
-# @wait: #optional wait for connect (not used for server
-# sockets, default: false)
+# @wait: #optional wait for incoming connection on server
+# sockets (default: false).
# @nodelay: #optional set TCP_NODELAY socket option (default: false)
-# @telnet: #optional enable telnet protocol (default: false)
+# @telnet: #optional enable telnet protocol on server
+# sockets (default: false)
#
# Since: 1.4
##
diff --git a/qemu-char.c b/qemu-char.c
index 63972ae4be..6cec5d7114 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2255,6 +2255,8 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
fd = inet_dgram_opts(opts, &local_err);
if (fd < 0) {
+ qerror_report_err(local_err);
+ error_free(local_err);
return NULL;
}
return qemu_chr_open_udp_fd(fd);
@@ -2604,7 +2606,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
memset(&ss, 0, ss_len);
if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
- error_setg(errp, "getsockname: %s", strerror(errno));
+ error_setg_errno(errp, errno, "getsockname");
return NULL;
}
@@ -2666,8 +2668,8 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
}
if (is_listen && is_waitconnect) {
- printf("QEMU waiting for connection on: %s\n",
- chr->filename);
+ fprintf(stderr, "QEMU waiting for connection on: %s\n",
+ chr->filename);
tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
qemu_set_nonblock(s->listen_fd);
}
@@ -3115,12 +3117,25 @@ static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
}
}
+static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
+ Error **errp)
+{
+ const char *chardev = qemu_opt_get(opts, "chardev");
+
+ if (chardev == NULL) {
+ error_setg(errp, "chardev: mux: no chardev given");
+ return;
+ }
+ backend->mux = g_new0(ChardevMux, 1);
+ backend->mux->chardev = g_strdup(chardev);
+}
+
typedef struct CharDriver {
const char *name;
/* old, pre qapi */
CharDriverState *(*open)(QemuOpts *opts);
/* new, qapi-based */
- int kind;
+ ChardevBackendKind kind;
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
} CharDriver;
@@ -3137,7 +3152,7 @@ void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *)
backends = g_slist_append(backends, s);
}
-void register_char_driver_qapi(const char *name, int kind,
+void register_char_driver_qapi(const char *name, ChardevBackendKind kind,
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
{
CharDriver *s;
@@ -3178,7 +3193,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
if (i == NULL) {
error_setg(errp, "chardev: backend \"%s\" not found",
qemu_opt_get(opts, "backend"));
- return NULL;
+ goto err;
}
if (!cd->open) {
@@ -3186,7 +3201,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
ChardevBackend *backend = g_new0(ChardevBackend, 1);
ChardevReturn *ret = NULL;
const char *id = qemu_opts_id(opts);
- const char *bid = NULL;
+ char *bid = NULL;
if (qemu_opt_get_bool(opts, "mux", 0)) {
bid = g_strdup_printf("%s-base", id);
@@ -3213,9 +3228,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
backend->kind = CHARDEV_BACKEND_KIND_MUX;
backend->mux->chardev = g_strdup(bid);
ret = qmp_chardev_add(id, backend, errp);
- if (error_is_set(errp)) {
- goto qapi_out;
- }
+ assert(!error_is_set(errp));
}
chr = qemu_chr_find(id);
@@ -3224,6 +3237,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
qapi_out:
qapi_free_ChardevBackend(backend);
qapi_free_ChardevReturn(ret);
+ g_free(bid);
return chr;
}
@@ -3483,6 +3497,9 @@ QemuOptsList qemu_chardev_opts = {
},{
.name = "size",
.type = QEMU_OPT_SIZE,
+ },{
+ .name = "chardev",
+ .type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
@@ -3494,7 +3511,7 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
{
HANDLE out;
- if (file->in) {
+ if (file->has_in) {
error_setg(errp, "input file not supported");
return NULL;
}
@@ -3530,7 +3547,7 @@ static int qmp_chardev_open_file_source(char *src, int flags,
TFR(fd = qemu_open(src, flags, 0666));
if (fd == -1) {
- error_setg(errp, "open %s: %s", src, strerror(errno));
+ error_setg_file_open(errp, errno, src);
}
return fd;
}
@@ -3545,7 +3562,7 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
return NULL;
}
- if (file->in) {
+ if (file->has_in) {
flags = O_RDONLY;
in = qmp_chardev_open_file_source(file->in, flags, errp);
if (error_is_set(errp)) {
@@ -3773,6 +3790,8 @@ static void register_types(void)
register_char_driver_qapi("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
register_char_driver_qapi("pipe", CHARDEV_BACKEND_KIND_PIPE,
qemu_chr_parse_pipe);
+ register_char_driver_qapi("mux", CHARDEV_BACKEND_KIND_MUX,
+ qemu_chr_parse_mux);
}
type_init(register_types);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 8022890391..185dd47a03 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -214,7 +214,7 @@ PCI UHCI USB controller and a virtual USB hub.
SMP is supported with up to 255 CPUs.
-QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
+QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
VGA BIOS.
QEMU uses YM3812 emulation by Tatsuyuki Satoh.
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 96eca2ad95..095716ecdb 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -848,9 +848,9 @@ int unix_nonblocking_connect(const char *path,
SocketAddress *socket_parse(const char *str, Error **errp)
{
- SocketAddress *addr = NULL;
+ SocketAddress *addr;
- addr = g_new(SocketAddress, 1);
+ addr = g_new0(SocketAddress, 1);
if (strstart(str, "unix:", NULL)) {
if (str[5] == '\0') {
error_setg(errp, "invalid Unix socket address");
@@ -871,7 +871,6 @@ SocketAddress *socket_parse(const char *str, Error **errp)
}
} else {
addr->kind = SOCKET_ADDRESS_KIND_INET;
- addr->inet = g_new(InetSocketAddress, 1);
addr->inet = inet_parse(str, errp);
if (addr->inet == NULL) {
goto fail;
@@ -904,7 +903,7 @@ int socket_connect(SocketAddress *addr, Error **errp,
case SOCKET_ADDRESS_KIND_FD:
fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
- if (callback) {
+ if (fd >= 0 && callback) {
qemu_set_nonblock(fd);
callback(fd, opaque);
}
@@ -964,7 +963,7 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
default:
error_setg(errp, "socket type unsupported for datagram");
- return -1;
+ fd = -1;
}
qemu_opts_del(opts);
return fd;