From: Corey Minyard <cminy...@mvista.com> 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 <cminy...@mvista.com> --- 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