#include "qemu-common.h"
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "hw/usb.h"
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
-#include <dirent.h>
#include <netdb.h>
#include <sys/select.h>
#ifdef CONFIG_BSD
MuxDriver *d;
chr = qemu_chr_alloc();
- d = g_malloc0(sizeof(MuxDriver));
+ d = g_new0(MuxDriver, 1);
chr->opaque = d;
d->drv = drv;
}
if (now_active) {
- iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
+ iwp->src = g_io_create_watch(iwp->channel,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
g_source_attach(iwp->src, NULL);
} else {
CharDriverState *chr;
GIOChannel *fd_in, *fd_out;
int max_size;
- QTAILQ_ENTRY(FDCharDriver) node;
} FDCharDriver;
/* Called with chr_write_lock held. */
FDCharDriver *s;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(FDCharDriver));
+ s = g_new0(FDCharDriver, 1);
s->fd_in = io_channel_from_fd(fd_in);
s->fd_out = io_channel_from_fd(fd_out);
qemu_set_nonblock(fd_out);
fprintf(stderr, "char device redirected to %s (label %s)\n",
pty_name, id);
- s = g_malloc0(sizeof(PtyCharDriver));
+ s = g_new0(PtyCharDriver, 1);
chr->opaque = s;
chr->chr_write = pty_chr_write;
chr->chr_update_read_handler = pty_chr_update_read_handler;
return NULL;
}
- drv = g_malloc0(sizeof(ParallelCharDriver));
+ drv = g_new0(ParallelCharDriver, 1);
drv->fd = fd;
drv->mode = IEEE1284_MODE_COMPAT;
WinCharState *s;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(WinCharState));
+ s = g_new0(WinCharState, 1);
chr->opaque = s;
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
WinCharState *s;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(WinCharState));
+ s = g_new0(WinCharState, 1);
chr->opaque = s;
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
WinCharState *s;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(WinCharState));
+ s = g_new0(WinCharState, 1);
s->hcom = fd_out;
chr->opaque = s;
chr->chr_write = win_chr_write;
int is_console = 0;
chr = qemu_chr_alloc();
- stdio = g_malloc0(sizeof(WinStdioCharState));
+ stdio = g_new0(WinStdioCharState, 1);
stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
NetCharDriver *s = NULL;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(NetCharDriver));
+ s = g_new0(NetCharDriver, 1);
s->fd = fd;
s->chan = io_channel_from_socket(s->fd);
TCPCharDriver *s = chr->opaque;
/* clear old pending fd array */
- if (s->write_msgfds) {
- g_free(s->write_msgfds);
- }
+ g_free(s->write_msgfds);
if (num) {
- s->write_msgfds = g_malloc(num * sizeof(int));
+ s->write_msgfds = g_new(int, num);
memcpy(s->write_msgfds, fds, num * sizeof(int));
}
#ifdef MSG_CMSG_CLOEXEC
flags |= MSG_CMSG_CLOEXEC;
#endif
- ret = recvmsg(s->fd, &msg, flags);
+ do {
+ ret = recvmsg(s->fd, &msg, flags);
+ } while (ret == -1 && errno == EINTR);
+
if (ret > 0 && s->is_unix) {
unix_process_msgfd(chr, &msg);
}
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
{
TCPCharDriver *s = chr->opaque;
- return qemu_recv(s->fd, buf, len, 0);
+ ssize_t ret;
+
+ do {
+ ret = qemu_recv(s->fd, buf, len, 0);
+ } while (ret == -1 && socket_error() == EINTR);
+
+ return ret;
}
#endif
uint8_t buf[READ_BUF_LEN];
int len, size;
- if (cond & G_IO_HUP) {
- /* connection closed */
- tcp_chr_disconnect(chr);
- return TRUE;
- }
-
if (!s->connected || s->max_size <= 0) {
return TRUE;
}
if (len > s->max_size)
len = s->max_size;
size = tcp_chr_recv(chr, (void *)buf, len);
- if (size == 0) {
+ if (size == 0 ||
+ (size < 0 &&
+ socket_error() != EAGAIN && socket_error() != EWOULDBLOCK)) {
/* connection closed */
tcp_chr_disconnect(chr);
} else if (size > 0) {
if (strstart(filename, "mon:", &p)) {
filename = p;
- qemu_opt_set(opts, "mux", "on");
+ qemu_opt_set(opts, "mux", "on", &error_abort);
if (strcmp(filename, "stdio") == 0) {
/* Monitor is muxed to stdio: do not exit on Ctrl+C by default
* but pass it to the guest. Handle this only for compat syntax,
* for -chardev syntax we have special option for this.
* This is what -nographic did, redirecting+muxing serial+monitor
* to stdio causing Ctrl+C to be passed to guest. */
- qemu_opt_set(opts, "signal", "off");
+ qemu_opt_set(opts, "signal", "off", &error_abort);
}
}
strcmp(filename, "braille") == 0 ||
strcmp(filename, "testdev") == 0 ||
strcmp(filename, "stdio") == 0) {
- qemu_opt_set(opts, "backend", filename);
+ qemu_opt_set(opts, "backend", filename, &error_abort);
return opts;
}
if (strstart(filename, "vc", &p)) {
- qemu_opt_set(opts, "backend", "vc");
+ qemu_opt_set(opts, "backend", "vc", &error_abort);
if (*p == ':') {
if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
/* pixels */
- qemu_opt_set(opts, "width", width);
- qemu_opt_set(opts, "height", height);
+ qemu_opt_set(opts, "width", width, &error_abort);
+ qemu_opt_set(opts, "height", height, &error_abort);
} else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
/* chars */
- qemu_opt_set(opts, "cols", width);
- qemu_opt_set(opts, "rows", height);
+ qemu_opt_set(opts, "cols", width, &error_abort);
+ qemu_opt_set(opts, "rows", height, &error_abort);
} else {
goto fail;
}
return opts;
}
if (strcmp(filename, "con:") == 0) {
- qemu_opt_set(opts, "backend", "console");
+ qemu_opt_set(opts, "backend", "console", &error_abort);
return opts;
}
if (strstart(filename, "COM", NULL)) {
- qemu_opt_set(opts, "backend", "serial");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "serial", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
if (strstart(filename, "file:", &p)) {
- qemu_opt_set(opts, "backend", "file");
- qemu_opt_set(opts, "path", p);
+ qemu_opt_set(opts, "backend", "file", &error_abort);
+ qemu_opt_set(opts, "path", p, &error_abort);
return opts;
}
if (strstart(filename, "pipe:", &p)) {
- qemu_opt_set(opts, "backend", "pipe");
- qemu_opt_set(opts, "path", p);
+ qemu_opt_set(opts, "backend", "pipe", &error_abort);
+ qemu_opt_set(opts, "path", p, &error_abort);
return opts;
}
if (strstart(filename, "tcp:", &p) ||
if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
goto fail;
}
- qemu_opt_set(opts, "backend", "socket");
- qemu_opt_set(opts, "host", host);
- qemu_opt_set(opts, "port", port);
+ qemu_opt_set(opts, "backend", "socket", &error_abort);
+ qemu_opt_set(opts, "host", host, &error_abort);
+ qemu_opt_set(opts, "port", port, &error_abort);
if (p[pos] == ',') {
- if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
+ qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
goto fail;
+ }
}
if (strstart(filename, "telnet:", &p))
- qemu_opt_set(opts, "telnet", "on");
+ qemu_opt_set(opts, "telnet", "on", &error_abort);
return opts;
}
if (strstart(filename, "udp:", &p)) {
- qemu_opt_set(opts, "backend", "udp");
+ qemu_opt_set(opts, "backend", "udp", &error_abort);
if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
host[0] = 0;
if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
goto fail;
}
}
- qemu_opt_set(opts, "host", host);
- qemu_opt_set(opts, "port", port);
+ qemu_opt_set(opts, "host", host, &error_abort);
+ qemu_opt_set(opts, "port", port, &error_abort);
if (p[pos] == '@') {
p += pos + 1;
if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
goto fail;
}
}
- qemu_opt_set(opts, "localaddr", host);
- qemu_opt_set(opts, "localport", port);
+ qemu_opt_set(opts, "localaddr", host, &error_abort);
+ qemu_opt_set(opts, "localport", port, &error_abort);
}
return opts;
}
if (strstart(filename, "unix:", &p)) {
- qemu_opt_set(opts, "backend", "socket");
- if (qemu_opts_do_parse(opts, p, "path") != 0)
+ qemu_opt_set(opts, "backend", "socket", &error_abort);
+ qemu_opts_do_parse(opts, p, "path", &local_err);
+ if (local_err) {
+ error_report_err(local_err);
goto fail;
+ }
return opts;
}
if (strstart(filename, "/dev/parport", NULL) ||
strstart(filename, "/dev/ppi", NULL)) {
- qemu_opt_set(opts, "backend", "parport");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "parport", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
if (strstart(filename, "/dev/", NULL)) {
- qemu_opt_set(opts, "backend", "tty");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "tty", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
chr = qemu_chr_alloc();
- s = g_malloc0(sizeof(TCPCharDriver));
+ s = g_new0(TCPCharDriver, 1);
s->fd = -1;
s->listen_fd = -1;