Make unix_connect_opts have the same signature as inet_connect_opts. This is required because both will be wrapped by socket_connect.
The logic is the same as inet_connect_opts, and qemu-char is already able to use the new functionality since it doesn't care about the kind of socket (unix vs. IP). Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- qemu-char.c | 2 +- qemu-sockets.c | 32 ++++++++++++++++++++++++++++---- qemu_socket.h | 2 +- 3 file modificati, 30 inserzioni(+), 6 rimozioni(-) diff --git a/qemu-char.c b/qemu-char.c index b33bdaa..665df93 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2453,7 +2453,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) if (is_listen) { fd = unix_listen_opts(opts, NULL); } else { - fd = unix_connect_opts(opts, NULL); + fd = unix_connect_opts(opts, false, NULL, NULL); } } else { if (is_listen) { diff --git a/qemu-sockets.c b/qemu-sockets.c index 8a7c5d4..778428f 100644 --- a/qemu-sockets.c +++ b/qemu-sockets.c @@ -587,27 +587,51 @@ err: return -1; } -int unix_connect_opts(QemuOpts *opts, Error **errp) +int unix_connect_opts(QemuOpts *opts, bool block, bool *in_progress, Error **errp) { struct sockaddr_un un; const char *path = qemu_opt_get(opts, "path"); int sock; + int rc; if (NULL == path) { error_setg(errp, "unix connect: no path specified\n"); return -1; } + if (in_progress) { + *in_progress = false; + } + sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { error_set(errp, QERR_SOCKET_CREATE_FAILED); return -1; } + if (!block) { + socket_set_nonblock(sock); + } memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); - if (connect(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { + do { + rc = 0; + if (connect(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { + rc = -socket_error(); + } + } while (rc == -EINTR); + +#ifdef _WIN32 + if (!block && (rc == -EINPROGRESS || rc == -EWOULDBLOCK + || rc == -WSAEALREADY)) { +#else + if (!block && (rc == -EINPROGRESS)) { +#endif + if (in_progress) { + *in_progress = true; + } + } else if (rc < 0) { error_set(errp, QERR_SOCKET_CONNECT_FAILED); close(sock); return -1; @@ -653,7 +677,7 @@ int unix_connect(const char *path, Error **errp) opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL); qemu_opt_set(opts, "path", path); - sock = unix_connect_opts(opts, errp); + sock = unix_connect_opts(opts, false, NULL, errp); qemu_opts_del(opts); return sock; } @@ -667,7 +691,7 @@ int unix_listen_opts(QemuOpts *opts, Error **errp) return -1; } -int unix_connect_opts(QemuOpts *opts, Error **errp) +int unix_connect_opts(QemuOpts *opts, bool block, bool *in_progress, Error **errp) { error_setg(errp, "unix sockets are not available on windows\n"); errno = ENOTSUP; diff --git a/qemu_socket.h b/qemu_socket.h index ad9e342..37dcafd 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -49,7 +49,7 @@ const char *inet_strfamily(int family); int unix_listen_opts(QemuOpts *opts, Error **errp); int unix_listen(const char *path, char *ostr, int olen, Error **errp); -int unix_connect_opts(QemuOpts *opts, Error **errp); +int unix_connect_opts(QemuOpts *opts, bool block, bool *in_progress, Error **errp); int unix_connect(const char *path, Error **errp); /* Old, ipv4 only bits. Don't use for new code. */ -- 1.7.12