From eaeba65304d9666309f246849adf1eff217b9868 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 14:54:05 +0200 Subject: qemu-char: cleanup qmp_chardev_add Use the usual idioms for error propagation. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 653ea10..f51c0aa 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4214,6 +4214,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, { ChardevReturn *ret = g_new0(ChardevReturn, 1); CharDriverState *base, *chr = NULL; + Error *local_err = NULL; chr = qemu_chr_find(id); if (chr) { @@ -4224,22 +4225,22 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, switch (backend->kind) { case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, errp); + chr = qmp_chardev_open_file(backend->file, &local_err); break; case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, errp); + chr = qmp_chardev_open_serial(backend->serial, &local_err); break; case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, errp); + chr = qmp_chardev_open_parallel(backend->parallel, &local_err); break; case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, errp); + chr = qmp_chardev_open_socket(backend->socket, &local_err); break; case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, errp); + chr = qmp_chardev_open_udp(backend->udp, &local_err); break; #ifdef HAVE_CHARDEV_TTY case CHARDEV_BACKEND_KIND_PTY: @@ -4252,7 +4253,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_MUX: base = qemu_chr_find(backend->mux->chardev); if (base == NULL) { - error_setg(errp, "mux: base chardev %s not found", + error_setg(&local_err, "mux: base chardev %s not found", backend->mux->chardev); break; } @@ -4290,11 +4291,11 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, errp); + chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); break; default: error_setg(errp, "unknown chardev backend (%d)", backend->kind); - break; + goto out_error; } /* @@ -4303,25 +4304,30 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, * error then. * TODO full conversion to Error API */ - if (chr == NULL && errp && !*errp) { - error_setg(errp, "Failed to create chardev"); - } - if (chr) { - chr->label = g_strdup(id); - chr->avail_connections = - (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; - if (!chr->filename) { - chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]); - } - if (!chr->explicit_be_open) { - qemu_chr_be_event(chr, CHR_EVENT_OPENED); + if (chr == NULL) { + if (local_err) { + error_propagate(errp, local_err); + } else { + error_setg(errp, "Failed to create chardev"); } - QTAILQ_INSERT_TAIL(&chardevs, chr, next); - return ret; - } else { - g_free(ret); - return NULL; + goto out_error; + } + + chr->label = g_strdup(id); + chr->avail_connections = + (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; + if (!chr->filename) { + chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]); } + if (!chr->explicit_be_open) { + qemu_chr_be_event(chr, CHR_EVENT_OPENED); + } + QTAILQ_INSERT_TAIL(&chardevs, chr, next); + return ret; + +out_error: + g_free(ret); + return NULL; } void qmp_chardev_remove(const char *id, Error **errp) -- cgit v1.1 From d809ab9521ace32a806cdf86ee7df40e1bf88443 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:46:23 +0200 Subject: qemu-char: cleanup HAVE_CHARDEV_* Move the #ifdef up into qmp_chardev_add, and avoid duplicating the code that reports unavailable backends. Split HAVE_CHARDEV_TTY into HAVE_CHARDEV_SERIAL and HAVE_CHARDEV_PTY. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index f51c0aa..7219d56 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1196,7 +1196,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ || defined(__GLIBC__) -#define HAVE_CHARDEV_TTY 1 +#define HAVE_CHARDEV_SERIAL 1 +#define HAVE_CHARDEV_PTY 1 typedef struct { GIOChannel *fd; @@ -1832,6 +1833,8 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd) #else /* _WIN32 */ +#define HAVE_CHARDEV_SERIAL 1 + typedef struct { int max_size; HANDLE hcom, hrecv, hsend; @@ -4069,10 +4072,10 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) return qemu_chr_open_fd(in, out); } +#ifdef HAVE_CHARDEV_SERIAL static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, Error **errp) { -#ifdef HAVE_CHARDEV_TTY int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); @@ -4081,16 +4084,12 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, } qemu_set_nonblock(fd); return qemu_chr_open_tty_fd(fd); -#else - error_setg(errp, "character device backend type 'serial' not supported"); - return NULL; -#endif } +#ifdef HAVE_CHARDEV_PARPORT static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, Error **errp) { -#ifdef HAVE_CHARDEV_PARPORT int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); @@ -4098,11 +4097,8 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, return NULL; } return qemu_chr_open_pp_fd(fd); -#else - error_setg(errp, "character device backend type 'parallel' not supported"); - return NULL; -#endif } +#endif #endif /* WIN32 */ @@ -4227,12 +4223,16 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_FILE: chr = qmp_chardev_open_file(backend->file, &local_err); break; +#ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: chr = qmp_chardev_open_serial(backend->serial, &local_err); break; +#endif +#ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: chr = qmp_chardev_open_parallel(backend->parallel, &local_err); break; +#endif case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; @@ -4242,7 +4242,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_UDP: chr = qmp_chardev_open_udp(backend->udp, &local_err); break; -#ifdef HAVE_CHARDEV_TTY +#ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: chr = qemu_chr_open_pty(id, ret); break; -- cgit v1.1 From 4ca172817a8c6df0145c16d80abdf04d53a56d92 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 14:55:59 +0200 Subject: qemu-char: add create to register_char_driver Having creation as a member of the CharDriver struct removes the need to export functions for qemu-char.c's usage. After the conversion, chardev backends implemented outside qemu-char.c will not need a stub creation function anymore. Ultimately all drivers will be converted. For now, support the case where cd->create == NULL. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 213 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 120 insertions(+), 93 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 7219d56..a6411d6 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3644,12 +3644,16 @@ typedef struct CharDriver { const char *name; ChardevBackendKind kind; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp); } CharDriver; static GSList *backends; void register_char_driver(const char *name, ChardevBackendKind kind, - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp)) + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp)) { CharDriver *s; @@ -3657,6 +3661,7 @@ void register_char_driver(const char *name, ChardevBackendKind kind, s->name = g_strdup(name); s->kind = kind; s->parse = parse; + s->create = create; backends = g_slist_append(backends, s); } @@ -4211,6 +4216,8 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, ChardevReturn *ret = g_new0(ChardevReturn, 1); CharDriverState *base, *chr = NULL; Error *local_err = NULL; + GSList *i; + CharDriver *cd; chr = qemu_chr_find(id); if (chr) { @@ -4219,98 +4226,113 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, return NULL; } - switch (backend->kind) { - case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, &local_err); - break; + for (i = backends; i; i = i->next) { + cd = i->data; + + if (cd->kind == backend->kind && cd->create) { + chr = cd->create(id, backend, ret, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto out_error; + } + break; + } + } + + if (chr == NULL) { + switch (backend->kind) { + case CHARDEV_BACKEND_KIND_FILE: + chr = qmp_chardev_open_file(backend->file, &local_err); + break; #ifdef HAVE_CHARDEV_SERIAL - case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, &local_err); - break; + case CHARDEV_BACKEND_KIND_SERIAL: + chr = qmp_chardev_open_serial(backend->serial, &local_err); + break; #endif #ifdef HAVE_CHARDEV_PARPORT - case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, &local_err); - break; + case CHARDEV_BACKEND_KIND_PARALLEL: + chr = qmp_chardev_open_parallel(backend->parallel, &local_err); + break; #endif - case CHARDEV_BACKEND_KIND_PIPE: - chr = qemu_chr_open_pipe(backend->pipe); - break; - case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, &local_err); - break; - case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, &local_err); - break; + case CHARDEV_BACKEND_KIND_PIPE: + chr = qemu_chr_open_pipe(backend->pipe); + break; + case CHARDEV_BACKEND_KIND_SOCKET: + chr = qmp_chardev_open_socket(backend->socket, &local_err); + break; + case CHARDEV_BACKEND_KIND_UDP: + chr = qmp_chardev_open_udp(backend->udp, &local_err); + break; #ifdef HAVE_CHARDEV_PTY - case CHARDEV_BACKEND_KIND_PTY: - chr = qemu_chr_open_pty(id, ret); - break; + case CHARDEV_BACKEND_KIND_PTY: + chr = qemu_chr_open_pty(id, ret); + break; #endif - case CHARDEV_BACKEND_KIND_NULL: - chr = qemu_chr_open_null(); - break; - case CHARDEV_BACKEND_KIND_MUX: - base = qemu_chr_find(backend->mux->chardev); - if (base == NULL) { - error_setg(&local_err, "mux: base chardev %s not found", - backend->mux->chardev); + case CHARDEV_BACKEND_KIND_NULL: + chr = qemu_chr_open_null(); + break; + case CHARDEV_BACKEND_KIND_MUX: + base = qemu_chr_find(backend->mux->chardev); + if (base == NULL) { + error_setg(&local_err, "mux: base chardev %s not found", + backend->mux->chardev); + break; + } + chr = qemu_chr_open_mux(base); + break; + case CHARDEV_BACKEND_KIND_MSMOUSE: + chr = qemu_chr_open_msmouse(); break; - } - chr = qemu_chr_open_mux(base); - break; - case CHARDEV_BACKEND_KIND_MSMOUSE: - chr = qemu_chr_open_msmouse(); - break; #ifdef CONFIG_BRLAPI - case CHARDEV_BACKEND_KIND_BRAILLE: - chr = chr_baum_init(); - break; + case CHARDEV_BACKEND_KIND_BRAILLE: + chr = chr_baum_init(); + break; #endif - case CHARDEV_BACKEND_KIND_TESTDEV: - chr = chr_testdev_init(); - break; - case CHARDEV_BACKEND_KIND_STDIO: - chr = qemu_chr_open_stdio(backend->stdio); - break; + case CHARDEV_BACKEND_KIND_TESTDEV: + chr = chr_testdev_init(); + break; + case CHARDEV_BACKEND_KIND_STDIO: + chr = qemu_chr_open_stdio(backend->stdio); + break; #ifdef _WIN32 - case CHARDEV_BACKEND_KIND_CONSOLE: - chr = qemu_chr_open_win_con(); - break; + case CHARDEV_BACKEND_KIND_CONSOLE: + chr = qemu_chr_open_win_con(); + break; #endif #ifdef CONFIG_SPICE - case CHARDEV_BACKEND_KIND_SPICEVMC: - chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); - break; - case CHARDEV_BACKEND_KIND_SPICEPORT: - chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); - break; + case CHARDEV_BACKEND_KIND_SPICEVMC: + chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); + break; + case CHARDEV_BACKEND_KIND_SPICEPORT: + chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); + break; #endif - case CHARDEV_BACKEND_KIND_VC: - chr = vc_init(backend->vc); - break; - case CHARDEV_BACKEND_KIND_RINGBUF: - case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); - break; - default: - error_setg(errp, "unknown chardev backend (%d)", backend->kind); - goto out_error; - } + case CHARDEV_BACKEND_KIND_VC: + chr = vc_init(backend->vc); + break; + case CHARDEV_BACKEND_KIND_RINGBUF: + case CHARDEV_BACKEND_KIND_MEMORY: + chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); + break; + default: + error_setg(errp, "unknown chardev backend (%d)", backend->kind); + goto out_error; + } - /* - * Character backend open hasn't been fully converted to the Error - * API. Some opens fail without setting an error. Set a generic - * error then. - * TODO full conversion to Error API - */ - if (chr == NULL) { - if (local_err) { - error_propagate(errp, local_err); - } else { - error_setg(errp, "Failed to create chardev"); + /* + * Character backend open hasn't been fully converted to the Error + * API. Some opens fail without setting an error. Set a generic + * error then. + * TODO full conversion to Error API + */ + if (chr == NULL) { + if (local_err) { + error_propagate(errp, local_err); + } else { + error_setg(errp, "Failed to create chardev"); + } + goto out_error; } - goto out_error; } chr->label = g_strdup(id); @@ -4349,32 +4371,37 @@ void qmp_chardev_remove(const char *id, Error **errp) static void register_types(void) { - register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL); + register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, + NULL); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, - qemu_chr_parse_socket); - register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp); + qemu_chr_parse_socket, NULL); + register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, + NULL); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, - qemu_chr_parse_ringbuf); + qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, - qemu_chr_parse_file_out); + qemu_chr_parse_file_out, NULL); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio); + qemu_chr_parse_stdio, NULL); register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial); + qemu_chr_parse_serial, NULL); register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial); + qemu_chr_parse_serial, NULL); register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel); + qemu_chr_parse_parallel, NULL); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel); - register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL); - register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL); + qemu_chr_parse_parallel, NULL); + register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, + NULL); + register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, + NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, - qemu_chr_parse_pipe); - register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux); + qemu_chr_parse_pipe, NULL); + register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, + NULL); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, - qemu_chr_parse_ringbuf); + qemu_chr_parse_ringbuf, NULL); /* this must be done after machine init, since we register FEs with muxes * as part of realize functions like serial_isa_realizefn when -nographic * is specified -- cgit v1.1 From fd5b036c5c6dc715bd06769a0023c6e1de2dadb4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:06:02 +0200 Subject: qemu-char: convert file backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index a6411d6..13fd394 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4010,8 +4010,12 @@ QemuOptsList qemu_chardev_opts = { #ifdef _WIN32 -static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevFile *file = backend->file; HANDLE out; if (file->has_in) { @@ -4055,8 +4059,12 @@ static int qmp_chardev_open_file_source(char *src, int flags, return fd; } -static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevFile *file = backend->file; int flags, in = -1, out; flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; @@ -4242,7 +4250,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, if (chr == NULL) { switch (backend->kind) { case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, &local_err); + abort(); break; #ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: @@ -4380,7 +4388,7 @@ static void register_types(void) register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, - qemu_chr_parse_file_out, NULL); + qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, qemu_chr_parse_stdio, NULL); register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, -- cgit v1.1 From 6511d39679f296162a90e71685651717a29e78e5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:08:05 +0200 Subject: qemu-char: convert serial backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 13fd394..8567580 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1886,7 +1886,7 @@ 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; @@ -1897,25 +1897,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; } @@ -1926,23 +1926,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); @@ -2047,7 +2047,8 @@ static int win_chr_poll(void *opaque) return 0; } -static CharDriverState *qemu_chr_open_win_path(const char *filename) +static CharDriverState *qemu_chr_open_win_path(const char *filename, + Error **errp) { CharDriverState *chr; WinCharState *s; @@ -2058,7 +2059,7 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename) 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); g_free(chr); return NULL; @@ -3465,6 +3466,7 @@ static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true); } +#ifdef HAVE_CHARDEV_SERIAL static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, Error **errp) { @@ -3477,6 +3479,7 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); } +#endif static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, Error **errp) @@ -4032,10 +4035,13 @@ static CharDriverState *qmp_chardev_open_file(const char *id, return qemu_chr_open_win_file(out); } -static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { - return qemu_chr_open_win_path(serial->device); + ChardevHostdev *serial = backend->serial; + return qemu_chr_open_win_path(serial->device, errp); } static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, @@ -4086,9 +4092,12 @@ static CharDriverState *qmp_chardev_open_file(const char *id, } #ifdef HAVE_CHARDEV_SERIAL -static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevHostdev *serial = backend->serial; int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); @@ -4098,6 +4107,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, qemu_set_nonblock(fd); return qemu_chr_open_tty_fd(fd); } +#endif #ifdef HAVE_CHARDEV_PARPORT static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, @@ -4252,11 +4262,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_FILE: abort(); break; -#ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, &local_err); + abort(); break; -#endif #ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: chr = qmp_chardev_open_parallel(backend->parallel, &local_err); @@ -4391,10 +4399,12 @@ static void register_types(void) qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, qemu_chr_parse_stdio, NULL); +#if defined HAVE_CHARDEV_SERIAL register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, NULL); + qemu_chr_parse_serial, qmp_chardev_open_serial); register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, NULL); + qemu_chr_parse_serial, qmp_chardev_open_serial); +#endif register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, qemu_chr_parse_parallel, NULL); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, -- cgit v1.1 From 38bfb1a63d05d000f128ea740442955070d9ff57 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:49:28 +0200 Subject: qemu-char: convert parallel backend to data-driven creation Conversion to Error * brings better error messages; before: qemu-system-x86_64: -chardev id=serial,backend=parallel,path=vl.c: Failed to create chardev After: qemu-system-x86_64: -chardev id=serial,backend=parallel,path=vl.c: not a parallel port: Inappropriate ioctl for device Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 8567580..ee6381b 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1753,12 +1753,13 @@ static void pp_close(CharDriverState *chr) qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_pp_fd(int fd) +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) { CharDriverState *chr; ParallelCharDriver *drv; if (ioctl(fd, PPCLAIM) < 0) { + error_setg_errno(errp, errno, "not a parallel port"); close(fd); return NULL; } @@ -1818,7 +1819,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) return 0; } -static CharDriverState *qemu_chr_open_pp_fd(int fd) +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) { CharDriverState *chr; @@ -3481,6 +3482,7 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } #endif +#ifdef HAVE_CHARDEV_PARPORT static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, Error **errp) { @@ -3493,6 +3495,7 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, backend->parallel = g_new0(ChardevHostdev, 1); backend->parallel->device = g_strdup(device); } +#endif static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, Error **errp) @@ -4044,13 +4047,6 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, return qemu_chr_open_win_path(serial->device, errp); } -static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, - Error **errp) -{ - error_setg(errp, "character device backend type 'parallel' not supported"); - return NULL; -} - #else /* WIN32 */ static int qmp_chardev_open_file_source(char *src, int flags, @@ -4110,16 +4106,19 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, #endif #ifdef HAVE_CHARDEV_PARPORT -static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, +static CharDriverState *qmp_chardev_open_parallel(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevHostdev *parallel = backend->parallel; int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); if (fd < 0) { return NULL; } - return qemu_chr_open_pp_fd(fd); + return qemu_chr_open_pp_fd(fd, errp); } #endif @@ -4265,11 +4264,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_SERIAL: abort(); break; -#ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, &local_err); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; @@ -4405,10 +4402,12 @@ static void register_types(void) register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial); #endif +#ifdef HAVE_CHARDEV_PARPORT register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, NULL); + qemu_chr_parse_parallel, qmp_chardev_open_parallel); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, NULL); + qemu_chr_parse_parallel, qmp_chardev_open_parallel); +#endif register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, NULL); register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, -- cgit v1.1 From 20cbe7a27980ef7e2ecd307cd210fc23b3f0762e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:14:07 +0200 Subject: qemu-char: convert pipe backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index ee6381b..44a5a8d 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1078,18 +1078,17 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) return chr; } -static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevHostdev *opts = backend->pipe; int fd_in, fd_out; char filename_in[CHR_MAX_FILENAME_SIZE]; char filename_out[CHR_MAX_FILENAME_SIZE]; const char *filename = opts->device; - if (filename == NULL) { - fprintf(stderr, "chardev: pipe: no filename given\n"); - return NULL; - } - snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename); snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename); TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY)); @@ -1101,6 +1100,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) close(fd_out); TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); if (fd_in < 0) { + error_setg_file_open(errp, errno, filename); return NULL; } } @@ -2084,7 +2084,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; @@ -2096,12 +2097,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; } @@ -2111,7 +2112,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; } @@ -2120,13 +2121,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; @@ -2147,8 +2148,12 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) } -static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevHostdev *opts = backend->pipe; const char *filename = opts->device; CharDriverState *chr; WinCharState *s; @@ -2159,7 +2164,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) 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); g_free(chr); return NULL; @@ -4268,7 +4273,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_PIPE: - chr = qemu_chr_open_pipe(backend->pipe); + abort(); break; case CHARDEV_BACKEND_KIND_SOCKET: chr = qmp_chardev_open_socket(backend->socket, &local_err); @@ -4413,7 +4418,7 @@ static void register_types(void) register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, - qemu_chr_parse_pipe, NULL); + qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, NULL); /* Bug-compatibility: */ -- cgit v1.1 From dbba8d1be3db5a52cfe200f219fbf8840d75cb14 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:15:53 +0200 Subject: qemu-char: convert socket backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 44a5a8d..d0de7ef 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4154,11 +4154,14 @@ static gboolean socket_reconnect_timeout(gpointer opaque) return false; } -static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock, +static CharDriverState *qmp_chardev_open_socket(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { CharDriverState *chr; TCPCharDriver *s; + ChardevSocket *sock = backend->socket; SocketAddress *addr = sock->addr; bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool is_listen = sock->has_server ? sock->server : true; @@ -4276,7 +4279,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, &local_err); + abort(); break; case CHARDEV_BACKEND_KIND_UDP: chr = qmp_chardev_open_udp(backend->udp, &local_err); @@ -4392,7 +4395,7 @@ static void register_types(void) register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, NULL); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, - qemu_chr_parse_socket, NULL); + qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, NULL); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, -- cgit v1.1 From e79b80daa252ffb4bc5c84c836714eb45ab3bb68 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:17:20 +0200 Subject: qemu-char: convert UDP backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index d0de7ef..de4d9d8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4223,9 +4223,12 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, return chr; } -static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp, +static CharDriverState *qmp_chardev_open_udp(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevUdp *udp = backend->udp; int fd; fd = socket_dgram(udp->remote, udp->local, errp); @@ -4282,7 +4285,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, &local_err); + abort(); break; #ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: @@ -4397,7 +4400,7 @@ static void register_types(void) register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, - NULL); + qmp_chardev_open_udp); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, -- cgit v1.1 From c2e75a432b907562cf93772b7d058d1ec8a8f8f1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:23:42 +0200 Subject: qemu-char: convert pty backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index de4d9d8..15c1a15 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1390,7 +1390,9 @@ static void pty_chr_close(struct CharDriverState *chr) } static CharDriverState *qemu_chr_open_pty(const char *id, - ChardevReturn *ret) + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; PtyCharDriver *s; @@ -1399,6 +1401,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id, master_fd = qemu_openpty_raw(&slave_fd, pty_name); if (master_fd < 0) { + error_setg_errno(errp, errno, "Failed to create PTY"); return NULL; } @@ -4287,11 +4290,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_UDP: abort(); break; -#ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: - chr = qemu_chr_open_pty(id, ret); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_NULL: chr = qemu_chr_open_null(); break; @@ -4419,8 +4420,10 @@ static void register_types(void) register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, qemu_chr_parse_parallel, qmp_chardev_open_parallel); #endif +#ifdef HAVE_CHARDEV_PTY register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, - NULL); + qemu_chr_open_pty); +#endif register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, -- cgit v1.1 From 0d64992b5dfe099b170a0b19922833cc82745620 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:24:29 +0200 Subject: qemu-char: convert null backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 15c1a15..5bacee8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -383,7 +383,10 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) return len; } -static CharDriverState *qemu_chr_open_null(void) +static CharDriverState *qemu_chr_open_null(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; @@ -4294,7 +4297,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_NULL: - chr = qemu_chr_open_null(); + abort(); break; case CHARDEV_BACKEND_KIND_MUX: base = qemu_chr_find(backend->mux->chardev); @@ -4397,7 +4400,7 @@ void qmp_chardev_remove(const char *id, Error **errp) static void register_types(void) { register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, - NULL); + qemu_chr_open_null); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, -- cgit v1.1 From 3c0e5a4a845c9e2823c9060631eeefebabc2f093 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:27:24 +0200 Subject: qemu-char: convert mux backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 5bacee8..6f2202a 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -682,11 +682,20 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) return d->drv->chr_add_watch(d->drv, cond); } -static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) +static CharDriverState *qemu_chr_open_mux(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { - CharDriverState *chr; + ChardevMux *mux = backend->mux; + CharDriverState *chr, *drv; MuxDriver *d; + drv = qemu_chr_find(mux->chardev); + if (drv == NULL) { + error_setg(errp, "mux: base chardev %s not found", mux->chardev); + return NULL; + } + chr = qemu_chr_alloc(); d = g_new0(MuxDriver, 1); @@ -4248,7 +4257,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, Error **errp) { ChardevReturn *ret = g_new0(ChardevReturn, 1); - CharDriverState *base, *chr = NULL; + CharDriverState *chr = NULL; Error *local_err = NULL; GSList *i; CharDriver *cd; @@ -4300,13 +4309,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_MUX: - base = qemu_chr_find(backend->mux->chardev); - if (base == NULL) { - error_setg(&local_err, "mux: base chardev %s not found", - backend->mux->chardev); - break; - } - chr = qemu_chr_open_mux(base); + abort(); break; case CHARDEV_BACKEND_KIND_MSMOUSE: chr = qemu_chr_open_msmouse(); @@ -4432,7 +4435,7 @@ static void register_types(void) register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, - NULL); + qemu_chr_open_mux); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, qemu_chr_parse_ringbuf, NULL); -- cgit v1.1 From 96d885b93b47243d2fc6ee826abaa8c0017282c9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:29:15 +0200 Subject: qemu-char: convert msmouse backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 6f2202a..64ca397 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4312,7 +4312,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_MSMOUSE: - chr = qemu_chr_open_msmouse(); + abort(); break; #ifdef CONFIG_BRLAPI case CHARDEV_BACKEND_KIND_BRAILLE: -- cgit v1.1 From e47666b8d1f0a7043d53671587058b3ce539b09d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:31:26 +0200 Subject: qemu-char: convert braille backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 64ca397..f2e3a35 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4314,11 +4314,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_MSMOUSE: abort(); break; -#ifdef CONFIG_BRLAPI case CHARDEV_BACKEND_KIND_BRAILLE: - chr = chr_baum_init(); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_TESTDEV: chr = chr_testdev_init(); break; -- cgit v1.1 From 0498790173e462ac3a7e4e0f3608704b8382dd10 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:33:42 +0200 Subject: qemu-char: convert testdev backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index f2e3a35..56bc7ed 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4318,7 +4318,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_TESTDEV: - chr = chr_testdev_init(); + abort(); break; case CHARDEV_BACKEND_KIND_STDIO: chr = qemu_chr_open_stdio(backend->stdio); -- cgit v1.1 From 8c84b25d975870bbed2e089fe61e037c58a69854 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:40:28 +0200 Subject: qemu-char: convert stdio backend to data-driven creation The backend now always returns errors via the Error* argument. This avoids a double error message. Before: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize qemu-system-x86_64: -chardev stdio,id=base: Failed to create chardev After: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 57 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 56bc7ed..faeffd4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1168,19 +1168,23 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) fd_chr_close(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevStdio *opts = backend->stdio; CharDriverState *chr; struct sigaction act; if (is_daemonized()) { - error_report("cannot use stdio with -daemonize"); + error_setg(errp, "cannot use stdio with -daemonize"); return NULL; } if (stdio_in_use) { - error_report("cannot use stdio by multiple character devices"); - exit(1); + error_setg(errp, "cannot use stdio by multiple character devices"); + return NULL; } stdio_in_use = true; @@ -2341,7 +2345,10 @@ static void win_stdio_close(CharDriverState *chr) g_free(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; WinStdioCharState *stdio; @@ -2353,8 +2360,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (stdio->hStdIn == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot open stdio: invalid handle\n"); - exit(1); + error_setg(errp, "cannot open stdio: invalid handle"); + return NULL; } is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; @@ -2366,25 +2373,30 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) if (is_console) { if (qemu_add_wait_object(stdio->hStdIn, win_stdio_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err1; } } else { DWORD dwId; stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, - chr, 0, &dwId); - - if (stdio->hInputThread == INVALID_HANDLE_VALUE - || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE + if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot create stdio thread or event\n"); - exit(1); + error_setg(errp, "cannot create event"); + goto err2; } if (qemu_add_wait_object(stdio->hInputReadyEvent, win_stdio_thread_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err2; + } + stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, + chr, 0, &dwId); + + if (stdio->hInputThread == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot create stdio thread"); + goto err3; } } @@ -2402,6 +2414,15 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) qemu_chr_fe_set_echo(chr, false); return chr; + +err3: + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); +err2: + CloseHandle(stdio->hInputReadyEvent); + CloseHandle(stdio->hInputDoneEvent); +err1: + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return NULL; } #endif /* !_WIN32 */ @@ -4321,7 +4342,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_STDIO: - chr = qemu_chr_open_stdio(backend->stdio); + abort(); break; #ifdef _WIN32 case CHARDEV_BACKEND_KIND_CONSOLE: @@ -4411,7 +4432,7 @@ static void register_types(void) register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio, NULL); + qemu_chr_parse_stdio, qemu_chr_open_stdio); #if defined HAVE_CHARDEV_SERIAL register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial); -- cgit v1.1 From 122e5ed4412cadce2d44a5f636e4d1bfc67c534b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:42:04 +0200 Subject: qemu-char: convert console backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index faeffd4..b74d6aa 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2204,7 +2204,10 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) return chr; } -static CharDriverState *qemu_chr_open_win_con(void) +static CharDriverState *qemu_chr_open_win_con(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE)); } @@ -4344,11 +4347,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_STDIO: abort(); break; -#ifdef _WIN32 case CHARDEV_BACKEND_KIND_CONSOLE: - chr = qemu_chr_open_win_con(); + abort(); break; -#endif #ifdef CONFIG_SPICE case CHARDEV_BACKEND_KIND_SPICEVMC: chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); @@ -4449,8 +4450,10 @@ static void register_types(void) register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, qemu_chr_open_pty); #endif +#ifdef _WIN32 register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, - NULL); + qemu_chr_open_win_con); +#endif register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, -- cgit v1.1 From 68145e178ac200a27b5f0ab342da80cf60ddd576 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:45:47 +0200 Subject: qemu-char: convert spice backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index b74d6aa..02ec080 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4350,14 +4350,12 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_CONSOLE: abort(); break; -#ifdef CONFIG_SPICE case CHARDEV_BACKEND_KIND_SPICEVMC: - chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); + abort(); break; case CHARDEV_BACKEND_KIND_SPICEPORT: - chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_VC: chr = vc_init(backend->vc); break; -- cgit v1.1 From fa19d02539a56ac20d03b2eef775be7ffcdd695a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:49:06 +0200 Subject: qemu-char: convert vc backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 02ec080..14cb253 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4357,7 +4357,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_VC: - chr = vc_init(backend->vc); + abort(); break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: -- cgit v1.1 From 479f09a130f774b0275134b5c44081ea71fe00b3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:51:14 +0200 Subject: qemu-char: convert ringbuf backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 14cb253..6632018 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3222,9 +3222,12 @@ static void ringbuf_chr_close(struct CharDriverState *chr) chr->opaque = NULL; } -static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts, +static CharDriverState *qemu_chr_open_ringbuf(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevRingbuf *opts = backend->ringbuf; CharDriverState *chr; RingBufCharDriver *d; @@ -4361,7 +4364,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); + abort(); break; default: error_setg(errp, "unknown chardev backend (%d)", backend->kind); @@ -4427,7 +4430,7 @@ static void register_types(void) register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, qmp_chardev_open_udp); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, - qemu_chr_parse_ringbuf, NULL); + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, @@ -4458,7 +4461,7 @@ static void register_types(void) qemu_chr_open_mux); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, - qemu_chr_parse_ringbuf, NULL); + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); /* this must be done after machine init, since we register FEs with muxes * as part of realize functions like serial_isa_realizefn when -nographic * is specified -- cgit v1.1 From 1c3af0f4f04bd6e6729783a48bb51ca1eb5c3baf Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:51:41 +0200 Subject: qemu-char: cleanup after completed conversion to cd->create All backends now return errors through Error*, so the "Failed to create chardev" placeholder error can only be reached if the backend is not available (and only from the chardev-add QMP command; instead, the -chardev command line option fails earlier). Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 80 ++++--------------------------------------------------------- 1 file changed, 4 insertions(+), 76 deletions(-) (limited to 'qemu-char.c') diff --git a/qemu-char.c b/qemu-char.c index 6632018..13371c4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4299,7 +4299,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, for (i = backends; i; i = i->next) { cd = i->data; - if (cd->kind == backend->kind && cd->create) { + if (cd->kind == backend->kind) { chr = cd->create(id, backend, ret, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -4310,81 +4310,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, } if (chr == NULL) { - switch (backend->kind) { - case CHARDEV_BACKEND_KIND_FILE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SERIAL: - abort(); - break; - case CHARDEV_BACKEND_KIND_PARALLEL: - abort(); - break; - case CHARDEV_BACKEND_KIND_PIPE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SOCKET: - abort(); - break; - case CHARDEV_BACKEND_KIND_UDP: - abort(); - break; - case CHARDEV_BACKEND_KIND_PTY: - abort(); - break; - case CHARDEV_BACKEND_KIND_NULL: - abort(); - break; - case CHARDEV_BACKEND_KIND_MUX: - abort(); - break; - case CHARDEV_BACKEND_KIND_MSMOUSE: - abort(); - break; - case CHARDEV_BACKEND_KIND_BRAILLE: - abort(); - break; - case CHARDEV_BACKEND_KIND_TESTDEV: - abort(); - break; - case CHARDEV_BACKEND_KIND_STDIO: - abort(); - break; - case CHARDEV_BACKEND_KIND_CONSOLE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SPICEVMC: - abort(); - break; - case CHARDEV_BACKEND_KIND_SPICEPORT: - abort(); - break; - case CHARDEV_BACKEND_KIND_VC: - abort(); - break; - case CHARDEV_BACKEND_KIND_RINGBUF: - case CHARDEV_BACKEND_KIND_MEMORY: - abort(); - break; - default: - error_setg(errp, "unknown chardev backend (%d)", backend->kind); - goto out_error; - } - - /* - * Character backend open hasn't been fully converted to the Error - * API. Some opens fail without setting an error. Set a generic - * error then. - * TODO full conversion to Error API - */ - if (chr == NULL) { - if (local_err) { - error_propagate(errp, local_err); - } else { - error_setg(errp, "Failed to create chardev"); - } - goto out_error; - } + assert(!i); + error_setg(errp, "chardev backend not available"); + goto out_error; } chr->label = g_strdup(id); -- cgit v1.1