diff --git a/include/qapi/error.h b/include/qapi/error.h index 79958011db..d712089f1a 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -67,12 +67,6 @@ void error_set_win32(Error **errp, int win32_err, ErrorClass err_class, */ void error_setg_file_open(Error **errp, int os_errno, const char *filename); -/** - * Returns true if an indirect pointer to an error is pointing to a valid - * error object. - */ -bool error_is_set(Error **errp); - /* * Get the error class of an error object. */ diff --git a/qemu-char.c b/qemu-char.c index 54ed244542..17b476edf0 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3204,6 +3204,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; @@ -3245,13 +3246,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, chr = NULL; backend->kind = cd->kind; if (cd->parse) { - cd->parse(opts, backend, errp); - if (error_is_set(errp)) { + cd->parse(opts, backend, &local_err); + if (local_err) { + error_propagate(errp, local_err); goto qapi_out; } } ret = qmp_chardev_add(bid ? bid : id, backend, errp); - if (error_is_set(errp)) { + if (!ret) { goto qapi_out; } @@ -3263,7 +3265,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, backend->kind = CHARDEV_BACKEND_KIND_MUX; backend->mux->chardev = g_strdup(bid); ret = qmp_chardev_add(id, backend, errp); - if (error_is_set(errp)) { + if (!ret) { chr = qemu_chr_find(bid); qemu_chr_delete(chr); chr = NULL; @@ -3620,18 +3622,18 @@ static int qmp_chardev_open_file_source(char *src, int flags, static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) { - int flags, in = -1, out = -1; + int flags, in = -1, out; flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; out = qmp_chardev_open_file_source(file->out, flags, errp); - if (error_is_set(errp)) { + if (out < 0) { return NULL; } if (file->has_in) { flags = O_RDONLY; in = qmp_chardev_open_file_source(file->in, flags, errp); - if (error_is_set(errp)) { + if (in < 0) { qemu_close(out); return NULL; } @@ -3647,7 +3649,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); - if (error_is_set(errp)) { + if (fd < 0) { return NULL; } qemu_set_nonblock(fd); @@ -3665,7 +3667,7 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); - if (error_is_set(errp)) { + if (fd < 0) { return NULL; } return qemu_chr_open_pp_fd(fd); @@ -3692,7 +3694,7 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock, } else { fd = socket_connect(addr, errp, NULL, NULL); } - if (error_is_set(errp)) { + if (fd < 0) { return NULL; } return qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, @@ -3705,7 +3707,7 @@ static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp, int fd; fd = socket_dgram(udp->remote, udp->local, errp); - if (error_is_set(errp)) { + if (fd < 0) { return NULL; } return qemu_chr_open_udp_fd(fd); @@ -3796,7 +3798,13 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, break; } - if (chr == NULL && !error_is_set(errp)) { + /* + * 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 && errp && !*errp) { error_setg(errp, "Failed to create chardev"); } if (chr) { diff --git a/util/error.c b/util/error.c index 66245ccd1f..2ace0d8dd9 100644 --- a/util/error.c +++ b/util/error.c @@ -142,11 +142,6 @@ Error *error_copy(const Error *err) return err_new; } -bool error_is_set(Error **errp) -{ - return (errp && *errp); -} - ErrorClass error_get_class(const Error *err) { return err->err_class; diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 8818d7c0de..627e60931a 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -354,6 +354,7 @@ static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp) int inet_connect_opts(QemuOpts *opts, Error **errp, NonBlockingConnectHandler *callback, void *opaque) { + Error *local_err = NULL; struct addrinfo *res, *e; int sock = -1; bool in_progress; @@ -372,24 +373,27 @@ int inet_connect_opts(QemuOpts *opts, Error **errp, } for (e = res; e != NULL; e = e->ai_next) { - if (error_is_set(errp)) { - error_free(*errp); - *errp = NULL; - } + error_free(local_err); + local_err = NULL; if (connect_state != NULL) { connect_state->current_addr = e; } - sock = inet_connect_addr(e, &in_progress, connect_state, errp); - if (in_progress) { - return sock; - } else if (sock >= 0) { - /* non blocking socket immediate success, call callback */ - if (callback != NULL) { - callback(sock, opaque); - } + sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); + if (sock >= 0) { break; } } + + if (sock < 0) { + error_propagate(errp, local_err); + } else if (in_progress) { + /* wait_for_connect() will do the rest */ + return sock; + } else { + if (callback) { + callback(sock, opaque); + } + } g_free(connect_state); freeaddrinfo(res); return sock;