[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 6/7] qemu-char: Clean up error handling in qmp_chard
From: |
minyard |
Subject: |
[Qemu-devel] [PATCH 6/7] qemu-char: Clean up error handling in qmp_chardev_add |
Date: |
Tue, 4 Mar 2014 18:38:56 -0600 |
From: Corey Minyard <address@hidden>
The open functions called by qmp_chardev_add could either return NULL
or set errp to return an error. Modify to just return errp, as that can
pass useful information where returning NULL cannot.
Signed-off-by: Corey Minyard <address@hidden>
---
backends/baum.c | 6 +-
backends/msmouse.c | 4 +-
hw/misc/ivshmem.c | 11 +-
include/sysemu/char.h | 10 +-
include/ui/console.h | 4 +-
include/ui/qemu-spice.h | 15 ++-
qemu-char.c | 336 ++++++++++++++++++++++--------------------------
spice-qemu-char.c | 15 ++-
ui/console.c | 10 +-
ui/gtk.c | 4 +-
10 files changed, 190 insertions(+), 225 deletions(-)
diff --git a/backends/baum.c b/backends/baum.c
index 9910a74..56cd00f 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -561,7 +561,7 @@ static void baum_close(struct CharDriverState *chr)
g_free(baum);
}
-CharDriverState *chr_baum_init(CharDriverState *chr)
+void chr_baum_init(CharDriverState *chr, Error **errp)
{
BaumDriverState *baum;
brlapi_handle_t *handle;
@@ -610,15 +610,15 @@ CharDriverState *chr_baum_init(CharDriverState *chr)
qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
- return chr;
+ return;
fail:
timer_free(baum->cellCount_timer);
brlapi__closeConnection(handle);
fail_handle:
+ error_setg(errp, "Failed to initialize baum");
g_free(handle);
g_free(baum);
- return NULL;
}
static void register_types(void)
diff --git a/backends/msmouse.c b/backends/msmouse.c
index b4e7a23..78998f9 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -63,15 +63,13 @@ static void msmouse_chr_close (struct CharDriverState *chr)
g_free (chr);
}
-CharDriverState *qemu_chr_open_msmouse(CharDriverState *chr)
+void qemu_chr_open_msmouse(CharDriverState *chr, Error **errp)
{
chr->chr_write = msmouse_chr_write;
chr->chr_close = msmouse_chr_close;
chr->explicit_be_open = true;
qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft
Mouse");
-
- return chr;
}
static void register_types(void)
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 75e83c3..5813f79 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -291,20 +291,15 @@ static CharDriverState* create_eventfd_chr_device(void *
opaque, EventNotifier *
{
/* create a event character device based on the passed eventfd */
IVShmemState *s = opaque;
- CharDriverState *chr, *newchr;
+ CharDriverState *chr;
int eventfd = event_notifier_get_fd(n);
- newchr = g_malloc0(sizeof(*chr));
- if (newchr == NULL) {
- fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
- exit(-1);
- }
- chr = qemu_chr_open_eventfd(newchr, eventfd);
+ chr = g_malloc0(sizeof(*chr));
if (chr == NULL) {
- g_free(newchr);
fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
exit(-1);
}
+ qemu_chr_open_eventfd(chr, eventfd);
qemu_chr_fe_claim_no_fail(chr);
/* if MSI is supported we need multiple interrupts */
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 1800c54..8604041 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -306,22 +306,22 @@ 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)(CharDriverState *, QemuOpts *),
- int (*recon_setup)(CharDriverState *));
+ void (*open)(CharDriverState *, QemuOpts *, Error
**),
+ int (*recon_setup)(CharDriverState *));
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 */
-CharDriverState *qemu_chr_open_eventfd(CharDriverState *chr, int eventfd);
+void qemu_chr_open_eventfd(CharDriverState *chr, int eventfd);
extern int term_escape_char;
CharDriverState *qemu_char_get_next_serial(void);
/* msmouse */
-CharDriverState *qemu_chr_open_msmouse(CharDriverState *chr);
+void qemu_chr_open_msmouse(CharDriverState *chr, Error **errp);
/* baum.c */
-CharDriverState *chr_baum_init(CharDriverState *chr);
+void chr_baum_init(CharDriverState *chr, Error **errp);
#endif
diff --git a/include/ui/console.h b/include/ui/console.h
index 572a1ff..18776d6 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -299,9 +299,9 @@ void qemu_console_copy(QemuConsole *con, int src_x, int
src_y,
DisplaySurface *qemu_console_surface(QemuConsole *con);
DisplayState *qemu_console_displaystate(QemuConsole *console);
-typedef CharDriverState *(VcHandler)(CharDriverState *chr, ChardevVC *vc);
+typedef void (VcHandler)(CharDriverState *chr, ChardevVC *vc, Error **errp);
-CharDriverState *vc_init(CharDriverState *chr, ChardevVC *vc);
+void vc_init(CharDriverState *chr, ChardevVC *vc, Error **errp);
void register_vc_handler(VcHandler *handler);
/* sdl.c */
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index 15220a1..85b1be3 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -48,16 +48,17 @@ int qemu_spice_migrate_info(const char *hostname, int port,
int tls_port,
void do_info_spice_print(Monitor *mon, const QObject *data);
void do_info_spice(Monitor *mon, QObject **ret_data);
-CharDriverState *qemu_chr_open_spice_vmc(CharDriverState *chr,
- const char *type);
+void qemu_chr_open_spice_vmc(CharDriverState *chr, const char *type,
+ Error **errp);
#if SPICE_SERVER_VERSION >= 0x000c02
-CharDriverState *qemu_chr_open_spice_port(CharDriverState *chr,
- const char *name);
+void qemu_chr_open_spice_port(CharDriverState *chr, const char *name,
+ Error **errp);
void qemu_spice_register_ports(void);
#else
-static inline CharDriverState *qemu_chr_open_spice_port(CharDriverState *chr,
- const char *name)
-{ return NULL; }
+static inline void qemu_chr_open_spice_port(CharDriverState *chr,
+ const char *name,
+ Error **errp)
+{ error_setg(errp, "open spice port not supported"); }
#endif
#else /* CONFIG_SPICE */
diff --git a/qemu-char.c b/qemu-char.c
index 427bb34..ae63836 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -560,8 +560,7 @@ static Notifier muxes_realize_notify = {
.notify = muxes_realize_done,
};
-static CharDriverState *qemu_chr_open_mux(CharDriverState *chr,
- CharDriverState *drv)
+static void qemu_chr_open_mux(CharDriverState *chr, CharDriverState *drv)
{
MuxDriver *d;
@@ -580,8 +579,6 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState
*chr,
*/
chr->explicit_be_open = muxes_realized ? 0 : 1;
chr->is_mux = 1;
-
- return chr;
}
@@ -950,9 +947,8 @@ static void fd_chr_close(struct CharDriverState *chr)
}
/* open a character device to a unix fd */
-static CharDriverState *qemu_chr_open_fd(CharDriverState *chr,
- int fd_in, int fd_out,
- int close_fds_on_close)
+static void qemu_chr_open_fd(CharDriverState *chr, int fd_in, int fd_out,
+ int close_fds_on_close)
{
FDCharDriver *s;
@@ -972,20 +968,18 @@ static CharDriverState *qemu_chr_open_fd(CharDriverState
*chr,
chr->chr_write = fd_chr_write;
chr->chr_update_read_handler = fd_chr_update_read_handler;
chr->chr_close = fd_chr_close;
-
- return chr;
}
-static CharDriverState *qemu_chr_open_pipe(CharDriverState *chr,
- ChardevHostdev *opts)
+static void qemu_chr_open_pipe(CharDriverState *chr, ChardevHostdev *opts,
+ Error **errp)
{
int fd_in, fd_out;
char filename_in[256], filename_out[256];
const char *filename = opts->device;
if (filename == NULL) {
- fprintf(stderr, "chardev: pipe: no filename given\n");
- return NULL;
+ error_setg(errp, "chardev: pipe: no filename given");
+ return;
}
snprintf(filename_in, 256, "%s.in", filename);
@@ -999,10 +993,11 @@ static CharDriverState
*qemu_chr_open_pipe(CharDriverState *chr,
close(fd_out);
TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
if (fd_in < 0) {
- return NULL;
+ error_setg_file_open(errp, errno, filename);
+ return;
}
}
- return qemu_chr_open_fd(chr, fd_in, fd_out, TRUE);
+ qemu_chr_open_fd(chr, fd_in, fd_out, TRUE);
}
/* init terminal so that we can grab keys */
@@ -1043,12 +1038,12 @@ static void qemu_chr_close_stdio(struct CharDriverState
*chr)
fd_chr_close(chr);
}
-static CharDriverState *qemu_chr_open_stdio(CharDriverState *chr,
- ChardevStdio *opts)
+static void qemu_chr_open_stdio(CharDriverState *chr, ChardevStdio *opts,
+ Error **errp)
{
if (is_daemonized()) {
- error_report("cannot use stdio with -daemonize");
- return NULL;
+ error_setg(errp, "cannot use stdio with -daemonize");
+ return;
}
old_fd0_flags = fcntl(0, F_GETFL);
tcgetattr (0, &oldtty);
@@ -1062,8 +1057,6 @@ static CharDriverState
*qemu_chr_open_stdio(CharDriverState *chr,
stdio_allow_signal = opts->signal;
}
qemu_chr_fe_set_echo(chr, false);
-
- return chr;
}
#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
@@ -1222,9 +1215,8 @@ static void pty_chr_close(struct CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_pty(CharDriverState *chr,
- const char *id,
- ChardevReturn *ret)
+static void qemu_chr_open_pty(CharDriverState *chr, const char *id,
+ ChardevReturn *ret, Error **errp)
{
PtyCharDriver *s;
int master_fd, slave_fd;
@@ -1232,7 +1224,8 @@ static CharDriverState *qemu_chr_open_pty(CharDriverState
*chr,
master_fd = qemu_openpty_raw(&slave_fd, pty_name);
if (master_fd < 0) {
- return NULL;
+ error_setg_errno(errp, errno, "getsockname");
+ return;
}
close(slave_fd);
@@ -1254,8 +1247,6 @@ static CharDriverState *qemu_chr_open_pty(CharDriverState
*chr,
s->fd = io_channel_from_fd(master_fd);
s->timer_tag = 0;
-
- return chr;
}
static void tty_serial_init(int fd, int speed,
@@ -1581,13 +1572,14 @@ static void pp_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_pp_fd(CharDriverState *chr, int fd)
+static void qemu_chr_open_pp_fd(CharDriverState *chr, int fd, Error **errp)
{
ParallelCharDriver *drv;
if (ioctl(fd, PPCLAIM) < 0) {
+ error_setg_errno(errp, errno, "ioctl");
close(fd);
- return NULL;
+ return;
}
drv = g_malloc0(sizeof(ParallelCharDriver));
@@ -1598,8 +1590,6 @@ static CharDriverState
*qemu_chr_open_pp_fd(CharDriverState *chr, int fd)
chr->chr_ioctl = pp_ioctl;
chr->chr_close = pp_close;
chr->opaque = drv;
-
- return chr;
}
#endif /* __linux__ */
@@ -1644,13 +1634,12 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void
*arg)
return 0;
}
-static CharDriverState *qemu_chr_open_pp_fd(CharDriverState *chr, int fd)
+static void qemu_chr_open_pp_fd(CharDriverState *chr, int fd, Error **errp)
{
chr->opaque = (void *)(intptr_t)fd;
chr->chr_write = null_chr_write;
chr->chr_ioctl = pp_ioctl;
chr->explicit_be_open = true;
- return chr;
}
#endif
@@ -1704,7 +1693,8 @@ static void win_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static int win_chr_init(CharDriverState *chr, const char *filename)
+static int win_chr_init(CharDriverState *chr, const char *filename,
+ Error **errp)
{
WinCharState *s = chr->opaque;
COMMCONFIG comcfg;
@@ -1715,25 +1705,25 @@ static int win_chr_init(CharDriverState *chr, const
char *filename)
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
+ error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
+ error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
+ error_setg(errp, "Failed CreateFile (%lu)", GetLastError());
s->hcom = NULL;
goto fail;
}
if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
- fprintf(stderr, "Failed SetupComm\n");
+ error_setg(errp, "Failed SetupComm");
goto fail;
}
@@ -1744,23 +1734,23 @@ static int win_chr_init(CharDriverState *chr, const
char *filename)
CommConfigDialog(filename, NULL, &comcfg);
if (!SetCommState(s->hcom, &comcfg.dcb)) {
- fprintf(stderr, "Failed SetCommState\n");
+ error_setg(errp, "Failed SetCommState");
goto fail;
}
if (!SetCommMask(s->hcom, EV_ERR)) {
- fprintf(stderr, "Failed SetCommMask\n");
+ error_setg(errp, "Failed SetCommMask");
goto fail;
}
cto.ReadIntervalTimeout = MAXDWORD;
if (!SetCommTimeouts(s->hcom, &cto)) {
- fprintf(stderr, "Failed SetCommTimeouts\n");
+ error_setg(errp, "Failed SetCommTimeouts");
goto fail;
}
if (!ClearCommError(s->hcom, &err, &comstat)) {
- fprintf(stderr, "Failed ClearCommError\n");
+ error_setg(errp, "Failed ClearCommError");
goto fail;
}
qemu_add_polling_cb(win_chr_poll, chr);
@@ -1864,8 +1854,8 @@ static int win_chr_poll(void *opaque)
return 0;
}
-static CharDriverState *qemu_chr_open_win_path(CharDriverState *chr,
- const char *filename)
+static void qemu_chr_open_win_path(CharDriverState *chr, const char *filename,
+ Error **errp)
{
WinCharState *s;
@@ -1874,11 +1864,10 @@ static CharDriverState
*qemu_chr_open_win_path(CharDriverState *chr,
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
- if (win_chr_init(chr, filename) < 0) {
+ if (win_chr_init(chr, filename, errp) < 0) {
g_free(s);
- return NULL;
+ return;
}
- return chr;
}
static int win_chr_pipe_poll(void *opaque)
@@ -1897,7 +1886,8 @@ static int win_chr_pipe_poll(void *opaque)
return 0;
}
-static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
+static int win_chr_pipe_init(CharDriverState *chr, const char *filename,
+ Error **errp)
{
WinCharState *s = chr->opaque;
OVERLAPPED ov;
@@ -1909,12 +1899,12 @@ static int win_chr_pipe_init(CharDriverState *chr,
const char *filename)
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
+ error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
+ error_setg(errp, "Failed CreateEvent");
goto fail;
}
@@ -1924,7 +1914,7 @@ static int win_chr_pipe_init(CharDriverState *chr, const
char *filename)
PIPE_WAIT,
MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
+ error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError());
s->hcom = NULL;
goto fail;
}
@@ -1933,13 +1923,13 @@ static int win_chr_pipe_init(CharDriverState *chr,
const char *filename)
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ret = ConnectNamedPipe(s->hcom, &ov);
if (ret) {
- fprintf(stderr, "Failed ConnectNamedPipe\n");
+ error_setg(errp, "Failed ConnectNamedPipe");
goto fail;
}
ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
if (!ret) {
- fprintf(stderr, "Failed GetOverlappedResult\n");
+ error_setg(errp, "Failed GetOverlappedResult");
if (ov.hEvent) {
CloseHandle(ov.hEvent);
ov.hEvent = NULL;
@@ -1960,8 +1950,8 @@ static int win_chr_pipe_init(CharDriverState *chr, const
char *filename)
}
-static CharDriverState *qemu_chr_open_pipe(CharDriverState *chr,
- ChardevHostdev *opts)
+static void qemu_chr_open_pipe(CharDriverState *chr, ChardevHostdev *opts,
+ Error **errp)
{
const char *filename = opts->device;
WinCharState *s;
@@ -1971,15 +1961,13 @@ static CharDriverState
*qemu_chr_open_pipe(CharDriverState *chr,
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
- if (win_chr_pipe_init(chr, filename) < 0) {
+ if (win_chr_pipe_init(chr, filename, errp) < 0) {
g_free(s);
- return NULL;
+ return;
}
- return chr;
}
-static CharDriverState *qemu_chr_open_win_file(CharDriverState *chr,
- HANDLE fd_out)
+static voidqemu_chr_open_win_file(CharDriverState *chr, HANDLE fd_out)
{
WinCharState *s;
@@ -1987,12 +1975,11 @@ static CharDriverState
*qemu_chr_open_win_file(CharDriverState *chr,
s->hcom = fd_out;
chr->opaque = s;
chr->chr_write = win_chr_write;
- return chr;
}
-static CharDriverState *qemu_chr_open_win_con(CharDriverState *chr)
+static void qemu_chr_open_win_con(CharDriverState *chr)
{
- return qemu_chr_open_win_file(chr, GetStdHandle(STD_OUTPUT_HANDLE));
+ qemu_chr_open_win_file(chr, GetStdHandle(STD_OUTPUT_HANDLE));
}
static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
@@ -2293,7 +2280,7 @@ static void udp_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_udp_fd(CharDriverState *chr, int fd)
+static void qemu_chr_open_udp_fd(CharDriverState *chr, int fd, Error **errp)
{
NetCharDriver *s = NULL;
@@ -2309,21 +2296,18 @@ static CharDriverState
*qemu_chr_open_udp_fd(CharDriverState *chr, int fd)
chr->chr_close = udp_chr_close;
/* be isn't opened until we get a connection */
chr->explicit_be_open = true;
- return chr;
}
-static CharDriverState *qemu_chr_open_udp(CharDriverState *chr, QemuOpts *opts)
+static void qemu_chr_open_udp(CharDriverState *chr, QemuOpts *opts,
+ Error **errp)
{
- Error *local_err = NULL;
int fd = -1;
- fd = inet_dgram_opts(opts, &local_err);
+ fd = inet_dgram_opts(opts, errp);
if (fd < 0) {
- qerror_report_err(local_err);
- error_free(local_err);
- return NULL;
+ return;
}
- return qemu_chr_open_udp_fd(chr, fd);
+ qemu_chr_open_udp_fd(chr, fd, errp);
}
/***********************************************************/
@@ -2535,9 +2519,9 @@ static gboolean tcp_chr_read(GIOChannel *chan,
GIOCondition cond, void *opaque)
}
#ifndef _WIN32
-CharDriverState *qemu_chr_open_eventfd(CharDriverState *chr, int eventfd)
+void qemu_chr_open_eventfd(CharDriverState *chr, int eventfd)
{
- return qemu_chr_open_fd(chr, eventfd, eventfd, FALSE);
+ qemu_chr_open_fd(chr, eventfd, eventfd, FALSE);
}
#endif
@@ -2684,11 +2668,10 @@ static void tcp_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
-static CharDriverState *qemu_chr_open_socket_fd(CharDriverState *chr,
- int fd, bool do_nodelay,
- bool is_listen, bool is_telnet,
- bool is_waitconnect,
- Error **errp)
+static void qemu_chr_open_socket_fd(CharDriverState *chr,
+ int fd, bool do_nodelay,
+ bool is_listen, bool is_telnet,
+ bool is_waitconnect, Error **errp)
{
TCPCharDriver *s = NULL;
char host[NI_MAXHOST], serv[NI_MAXSERV];
@@ -2699,7 +2682,7 @@ static CharDriverState
*qemu_chr_open_socket_fd(CharDriverState *chr,
memset(&ss, 0, ss_len);
if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) != 0) {
error_setg_errno(errp, errno, "getsockname");
- return NULL;
+ return;
}
s = g_malloc0(sizeof(TCPCharDriver));
@@ -2761,13 +2744,11 @@ static CharDriverState
*qemu_chr_open_socket_fd(CharDriverState *chr,
tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
qemu_set_nonblock(s->listen_fd);
}
- return chr;
}
-static CharDriverState *qemu_chr_open_socket(CharDriverState *chr,
- QemuOpts *opts)
+static void qemu_chr_open_socket(CharDriverState *chr,
+ QemuOpts *opts, Error **errp)
{
- Error *local_err = NULL;
int fd = -1;
bool is_listen = qemu_opt_get_bool(opts, "server", false);
@@ -2781,15 +2762,15 @@ static CharDriverState
*qemu_chr_open_socket(CharDriverState *chr,
if (is_unix) {
if (is_listen) {
- fd = unix_listen_opts(opts, &local_err);
+ fd = unix_listen_opts(opts, errp);
} else {
- fd = unix_connect_opts(opts, &local_err, NULL, NULL);
+ fd = unix_connect_opts(opts, errp, NULL, NULL);
}
} else {
if (is_listen) {
- fd = inet_listen_opts(opts, 0, &local_err);
+ fd = inet_listen_opts(opts, 0, errp);
} else {
- fd = inet_connect_opts(opts, &local_err, NULL, NULL);
+ fd = inet_connect_opts(opts, errp, NULL, NULL);
}
}
if (fd < 0) {
@@ -2800,18 +2781,12 @@ static CharDriverState
*qemu_chr_open_socket(CharDriverState *chr,
qemu_set_nonblock(fd);
qemu_chr_open_socket_fd(chr, fd, do_nodelay, is_listen, is_telnet,
- is_waitconnect, &local_err);
- if (local_err) {
- goto fail;
+ is_waitconnect, errp);
+ if (!error_is_set(errp)) {
+ return;
}
- return chr;
-
fail:
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- }
if (fd >= 0) {
closesocket(fd);
}
@@ -2819,7 +2794,6 @@ static CharDriverState
*qemu_chr_open_socket(CharDriverState *chr,
g_free(chr->opaque);
chr->opaque = NULL;
}
- return NULL;
}
/*********************************************************/
@@ -2879,9 +2853,8 @@ static void ringbuf_chr_close(struct CharDriverState *chr)
chr->opaque = NULL;
}
-static CharDriverState *qemu_chr_open_ringbuf(struct CharDriverState *chr,
- ChardevRingbuf *opts,
- Error **errp)
+static void qemu_chr_open_ringbuf(struct CharDriverState *chr,
+ ChardevRingbuf *opts, Error **errp)
{
RingBufCharDriver *d;
@@ -2892,7 +2865,8 @@ static CharDriverState *qemu_chr_open_ringbuf(struct
CharDriverState *chr,
/* The size must be power of 2 */
if (d->size & (d->size - 1)) {
error_setg(errp, "size of ringbuf chardev must be power of two");
- goto fail;
+ g_free(d);
+ return;
}
d->prod = 0;
@@ -2902,12 +2876,6 @@ static CharDriverState *qemu_chr_open_ringbuf(struct
CharDriverState *chr,
chr->opaque = d;
chr->chr_write = ringbuf_chr_write;
chr->chr_close = ringbuf_chr_close;
-
- return chr;
-
-fail:
- g_free(d);
- return NULL;
}
static bool chr_is_ringbuf(const CharDriverState *chr)
@@ -3230,7 +3198,7 @@ typedef struct CharDriver {
const char *name;
int (*recon_setup)(CharDriverState *);
/* old, pre qapi */
- CharDriverState *(*open)(CharDriverState *chr, QemuOpts *opts);
+ void (*open)(CharDriverState *chr, QemuOpts *opts, Error **errp);
/* new, qapi-based */
ChardevBackendKind kind;
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
@@ -3239,7 +3207,7 @@ typedef struct CharDriver {
static GSList *backends;
void register_char_driver(const char *name,
- CharDriverState *(*open)(CharDriverState*,QemuOpts
*),
+ void (*open)(CharDriverState *, QemuOpts *, Error
**),
int (*recon_setup)(CharDriverState *))
{
CharDriver *s;
@@ -3271,12 +3239,20 @@ static void generic_recon_state_change(void *opaque,
int is_open)
if (!is_open) {
struct CharDriver *cd = chr->backend->data;
+ Error *local_err = NULL;
if (chr->be_open) {
return;
}
- cd->open(chr, chr->opts);
+ cd->open(chr, chr->opts, &local_err);
+ if (error_is_set(&local_err)) {
+ fprintf(stderr, "chardev: opening backend \"%s\" failed: %s."
+ " Will retry in %llu seconds\n",
+ chr->label, error_get_pretty(local_err),
+ (unsigned long long) chr->recon->recon_time);
+ error_free(local_err);
+ }
} else {
void (*chr_close)(struct CharDriverState *chr) = chr->chr_close;
@@ -3313,6 +3289,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s),
Error **errp)
{
+ Error *local_err = NULL;
CharDriver *cd;
CharDriverState *chr;
GSList *i;
@@ -3419,14 +3396,21 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
}
}
- if (!cd->open(chr, opts)) {
- if (!chr->recon) {
+ cd->open(chr, opts, &local_err);
+ if (error_is_set(&local_err)) {
+ if (chr->recon) {
+ fprintf(stderr, "chardev: opening backend \"%s\" failed: %s."
+ " Will retry in %llu seconds\n",
+ qemu_opts_id(opts), error_get_pretty(local_err),
+ (unsigned long long) chr->recon->recon_time);
+ } else {
/* Reconnect is not enabled, give up */
- fprintf(stderr, "chardev: opening backend \"%s\" failed\n",
- qemu_opt_get(opts, "backend"));
+ error_setg(errp, "chardev: opening backend \"%s\" failed: %s",
+ qemu_opts_id(opts), error_get_pretty(local_err));
g_free(chr);
return NULL;
}
+ error_free(local_err);
}
if (!chr->filename)
@@ -3724,38 +3708,35 @@ QemuOptsList qemu_chardev_opts = {
#ifdef _WIN32
-static CharDriverState *qmp_chardev_open_file(CharDriverState *chr,
- ChardevFile *file, Error **errp)
+static void qmp_chardev_open_file(CharDriverState *chr,
+ ChardevFile *file, Error **errp)
{
HANDLE out;
if (file->has_in) {
error_setg(errp, "input file not supported");
- return NULL;
+ return;
}
out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (out == INVALID_HANDLE_VALUE) {
error_setg(errp, "open %s failed", file->out);
- return NULL;
+ return;
}
- return qemu_chr_open_win_file(out);
+ qemu_chr_open_win_file(out);
}
-static CharDriverState *qmp_chardev_open_serial(CharDriverState *chr,
- ChardevHostdev *serial,
- Error **errp)
+static void qmp_chardev_open_serial(CharDriverState *chr,
+ ChardevHostdev *serial, Error **errp)
{
- return qemu_chr_open_win_path(serial->device);
+ qemu_chr_open_win_path(serial->device, errp);
}
-static CharDriverState *qmp_chardev_open_parallel(CharDriverState *chr,
- ChardevHostdev *parallel,
- Error **errp)
+static void qmp_chardev_open_parallel(CharDriverState *chr,
+ ChardevHostdev *parallel, Error **errp)
{
error_setg(errp, "character device backend type 'parallel' not supported");
- return NULL;
}
#else /* WIN32 */
@@ -3772,15 +3753,15 @@ static int qmp_chardev_open_file_source(char *src, int
flags,
return fd;
}
-static CharDriverState *qmp_chardev_open_file(CharDriverState *chr,
- ChardevFile *file, Error **errp)
+static void qmp_chardev_open_file(CharDriverState *chr,
+ ChardevFile *file, Error **errp)
{
int flags, in = -1, out = -1;
flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
out = qmp_chardev_open_file_source(file->out, flags, errp);
if (error_is_set(errp)) {
- return NULL;
+ return;
}
if (file->has_in) {
@@ -3788,55 +3769,50 @@ static CharDriverState
*qmp_chardev_open_file(CharDriverState *chr,
in = qmp_chardev_open_file_source(file->in, flags, errp);
if (error_is_set(errp)) {
qemu_close(out);
- return NULL;
+ return;
}
}
- return qemu_chr_open_fd(chr, in, out, TRUE);
+ qemu_chr_open_fd(chr, in, out, TRUE);
}
-static CharDriverState *qmp_chardev_open_serial(CharDriverState *chr,
- ChardevHostdev *serial,
- Error **errp)
+static void qmp_chardev_open_serial(CharDriverState *chr,
+ ChardevHostdev *serial, Error **errp)
{
#ifdef HAVE_CHARDEV_TTY
int fd;
fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
if (error_is_set(errp)) {
- return NULL;
+ return;
}
qemu_set_nonblock(fd);
- return qemu_chr_open_tty_fd(chr, fd);
+ qemu_chr_open_tty_fd(chr, fd);
#else
error_setg(errp, "character device backend type 'serial' not supported");
- return NULL;
#endif
}
-static CharDriverState *qmp_chardev_open_parallel(CharDriverState *chr,
- ChardevHostdev *parallel,
- Error **errp)
+static void qmp_chardev_open_parallel(CharDriverState *chr,
+ ChardevHostdev *parallel, Error **errp)
{
#ifdef HAVE_CHARDEV_PARPORT
int fd;
fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
if (error_is_set(errp)) {
- return NULL;
+ return;
}
- return qemu_chr_open_pp_fd(chr, fd);
+ qemu_chr_open_pp_fd(chr, fd, errp);
#else
error_setg(errp, "character device backend type 'parallel' not supported");
- return NULL;
#endif
}
#endif /* WIN32 */
-static CharDriverState *qmp_chardev_open_socket(CharDriverState *chr,
- ChardevSocket *sock,
- Error **errp)
+static void qmp_chardev_open_socket(CharDriverState *chr,
+ ChardevSocket *sock, Error **errp)
{
SocketAddress *addr = sock->addr;
bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
@@ -3851,30 +3827,29 @@ static CharDriverState
*qmp_chardev_open_socket(CharDriverState *chr,
fd = socket_connect(addr, errp, NULL, NULL);
}
if (error_is_set(errp)) {
- return NULL;
+ return;
}
- return qemu_chr_open_socket_fd(chr, fd, do_nodelay, is_listen,
- is_telnet, is_waitconnect, errp);
+ qemu_chr_open_socket_fd(chr, fd, do_nodelay, is_listen,
+ is_telnet, is_waitconnect, errp);
}
-static CharDriverState *qmp_chardev_open_udp(CharDriverState *chr,
- ChardevUdp *udp,
- Error **errp)
+static void qmp_chardev_open_udp(CharDriverState *chr,
+ ChardevUdp *udp, Error **errp)
{
int fd;
fd = socket_dgram(udp->remote, udp->local, errp);
if (error_is_set(errp)) {
- return NULL;
+ return;
}
- return qemu_chr_open_udp_fd(chr, fd);
+ qemu_chr_open_udp_fd(chr, fd, errp);
}
ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
Error **errp)
{
ChardevReturn *ret = g_new0(ChardevReturn, 1);
- CharDriverState *base, *chr, *newchr;
+ CharDriverState *base, *chr;
chr = qemu_chr_find(id);
if (chr) {
@@ -3883,34 +3858,34 @@ ChardevReturn *qmp_chardev_add(const char *id,
ChardevBackend *backend,
return NULL;
}
- newchr = g_malloc0(sizeof(CharDriverState));
+ chr = g_malloc0(sizeof(CharDriverState));
switch (backend->kind) {
case CHARDEV_BACKEND_KIND_FILE:
- chr = qmp_chardev_open_file(newchr, backend->file, errp);
+ qmp_chardev_open_file(chr, backend->file, errp);
break;
case CHARDEV_BACKEND_KIND_SERIAL:
- chr = qmp_chardev_open_serial(newchr, backend->serial, errp);
+ qmp_chardev_open_serial(chr, backend->serial, errp);
break;
case CHARDEV_BACKEND_KIND_PARALLEL:
- chr = qmp_chardev_open_parallel(newchr, backend->parallel, errp);
+ qmp_chardev_open_parallel(chr, backend->parallel, errp);
break;
case CHARDEV_BACKEND_KIND_PIPE:
- chr = qemu_chr_open_pipe(newchr, backend->pipe);
+ qemu_chr_open_pipe(chr, backend->pipe, errp);
break;
case CHARDEV_BACKEND_KIND_SOCKET:
- chr = qmp_chardev_open_socket(newchr, backend->socket, errp);
+ qmp_chardev_open_socket(chr, backend->socket, errp);
break;
case CHARDEV_BACKEND_KIND_UDP:
- chr = qmp_chardev_open_udp(newchr, backend->udp, errp);
+ qmp_chardev_open_udp(chr, backend->udp, errp);
break;
#ifdef HAVE_CHARDEV_TTY
case CHARDEV_BACKEND_KIND_PTY:
- chr = qemu_chr_open_pty(newchr, id, ret);
+ qemu_chr_open_pty(chr, id, ret, errp);
break;
#endif
case CHARDEV_BACKEND_KIND_NULL:
- chr = qemu_chr_open_null(newchr);
+ chr = qemu_chr_open_null(chr);
break;
case CHARDEV_BACKEND_KIND_MUX:
base = qemu_chr_find(backend->mux->chardev);
@@ -3919,48 +3894,45 @@ ChardevReturn *qmp_chardev_add(const char *id,
ChardevBackend *backend,
backend->mux->chardev);
break;
}
- chr = qemu_chr_open_mux(newchr, base);
+ qemu_chr_open_mux(chr, base);
break;
case CHARDEV_BACKEND_KIND_MSMOUSE:
- chr = qemu_chr_open_msmouse(newchr);
+ qemu_chr_open_msmouse(chr, errp);
break;
#ifdef CONFIG_BRLAPI
case CHARDEV_BACKEND_KIND_BRAILLE:
- chr = chr_baum_init(newchr);
+ chr_baum_init(chr, errp);
break;
#endif
case CHARDEV_BACKEND_KIND_STDIO:
- chr = qemu_chr_open_stdio(newchr, backend->stdio);
+ qemu_chr_open_stdio(chr, backend->stdio, errp);
break;
#ifdef _WIN32
case CHARDEV_BACKEND_KIND_CONSOLE:
- chr = qemu_chr_open_win_con(newchr);
+ qemu_chr_open_win_con(chr);
break;
#endif
#ifdef CONFIG_SPICE
case CHARDEV_BACKEND_KIND_SPICEVMC:
- chr = qemu_chr_open_spice_vmc(newchr, backend->spicevmc->type);
+ qemu_chr_open_spice_vmc(chr, backend->spicevmc->type, errp);
break;
case CHARDEV_BACKEND_KIND_SPICEPORT:
- chr = qemu_chr_open_spice_port(newchr, backend->spiceport->fqdn);
+ qemu_chr_open_spice_port(chr, backend->spiceport->fqdn, errp);
break;
#endif
case CHARDEV_BACKEND_KIND_VC:
- chr = vc_init(newchr, backend->vc);
+ vc_init(chr, backend->vc, errp);
break;
case CHARDEV_BACKEND_KIND_RINGBUF:
case CHARDEV_BACKEND_KIND_MEMORY:
- chr = qemu_chr_open_ringbuf(newchr, backend->ringbuf, errp);
+ qemu_chr_open_ringbuf(chr, backend->ringbuf, errp);
break;
default:
error_setg(errp, "unknown chardev backend (%d)", backend->kind);
break;
}
- if (chr == NULL && !error_is_set(errp)) {
- error_setg(errp, "Failed to create chardev");
- }
- if (chr) {
+ if (!error_is_set(errp)) {
chr->label = g_strdup(id);
chr->avail_connections =
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
@@ -3971,12 +3943,12 @@ ChardevReturn *qmp_chardev_add(const char *id,
ChardevBackend *backend,
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
- return ret;
} else {
- g_free(newchr);
+ g_free(chr);
g_free(ret);
- return NULL;
+ ret = NULL;
}
+ return ret;
}
void qmp_chardev_remove(const char *id, Error **errp)
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index c2f5375..8d999f1 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -261,8 +261,8 @@ static void print_allowed_subtypes(void)
fprintf(stderr, "\n");
}
-static CharDriverState *chr_open(CharDriverState *chr, const char *subtype,
- void (*set_fe_open)(struct CharDriverState *, int))
+static void chr_open(CharDriverState *chr, const char *subtype,
+ void (*set_fe_open)(struct CharDriverState *, int))
{
SpiceCharDriver *s;
@@ -279,18 +279,18 @@ static CharDriverState *chr_open(CharDriverState *chr,
const char *subtype,
chr->chr_fe_event = spice_chr_fe_event;
QLIST_INSERT_HEAD(&spice_chars, s, next);
-
- return chr;
}
-CharDriverState *qemu_chr_open_spice_vmc(CharDriverState *chr, const char
*type)
+void qemu_chr_open_spice_vmc(CharDriverState *chr, const char *type,
+ Error *errp)
{
const char **psubtype = spice_server_char_device_recognized_subtypes();
if (type == NULL) {
fprintf(stderr, "spice-qemu-char: missing name parameter\n");
print_allowed_subtypes();
- return NULL;
+ error_setg(errp, "open spice vmc failed");
+ return;
}
for (; *psubtype != NULL; ++psubtype) {
if (strcmp(type, *psubtype) == 0) {
@@ -300,7 +300,8 @@ CharDriverState *qemu_chr_open_spice_vmc(CharDriverState
*chr, const char *type)
if (*psubtype == NULL) {
fprintf(stderr, "spice-qemu-char: unsupported type: %s\n", type);
print_allowed_subtypes();
- return NULL;
+ error_setg(errp, "open spice vmc failed");
+ return;
}
return chr_open(chr, type, spice_vmc_set_fe_open);
diff --git a/ui/console.c b/ui/console.c
index 0ac45c5..a204ce2 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1724,7 +1724,7 @@ static void text_console_do_init(CharDriverState *chr,
DisplayState *ds)
chr->init(chr);
}
-static CharDriverState *text_console_init(CharDriverState *chr, ChardevVC *vc)
+static void text_console_init(CharDriverState *chr, ChardevVC *vc, Error
**errp)
{
QemuConsole *s;
unsigned width = 0;
@@ -1751,7 +1751,8 @@ static CharDriverState *text_console_init(CharDriverState
*chr, ChardevVC *vc)
}
if (!s) {
- return NULL;
+ error_setg(errp, "Unable to create a new vc console");
+ return;
}
s->chr = chr;
@@ -1765,14 +1766,13 @@ static CharDriverState
*text_console_init(CharDriverState *chr, ChardevVC *vc)
if (display_state) {
text_console_do_init(chr, display_state);
}
- return chr;
}
static VcHandler *vc_handler = text_console_init;
-CharDriverState *vc_init(CharDriverState *chr, ChardevVC *vc)
+void vc_init(CharDriverState *chr, ChardevVC *vc, Error **errp)
{
- return vc_handler(chr, vc);
+ vc_handler(chr, vc, errp);
}
void register_vc_handler(VcHandler *handler)
diff --git a/ui/gtk.c b/ui/gtk.c
index 0ecc26a..a970860 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1125,15 +1125,13 @@ static int gd_vc_chr_write(CharDriverState *chr, const
uint8_t *buf, int len)
static int nb_vcs;
static CharDriverState *vcs[MAX_VCS];
-static CharDriverState *gd_vc_handler(CharDriverState *chr, ChardevVC *unused)
+static void gd_vc_handler(CharDriverState *chr, ChardevVC *unused, Error
**errp)
{
chr->chr_write = gd_vc_chr_write;
/* defer OPENED events until our vc is fully initialized */
chr->explicit_be_open = true;
vcs[nb_vcs++] = chr;
-
- return chr;
}
void early_gtk_display_init(void)
--
1.8.3.1
- [Qemu-devel] [PATCH 2/7] qemu-char: Allow a chardev to reconnect if disconnected, (continued)
[Qemu-devel] [PATCH 3/7] qemu-char: Wait until socket connect to report connected, minyard, 2014/03/04
[Qemu-devel] [PATCH 4/7] qemu-char: remove free of chr from win_stdio_close, minyard, 2014/03/04
[Qemu-devel] [PATCH 5/7] qemu-char: Close fd at end of file, minyard, 2014/03/04
[Qemu-devel] [PATCH 6/7] qemu-char: Clean up error handling in qmp_chardev_add,
minyard <=
[Qemu-devel] [PATCH 7/7] console: Don't use the console if NULL, minyard, 2014/03/04