Signed-off-by: Corentin Chary <corentin.ch...@gmail.com> --- osdep.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu_socket.h | 1 + 2 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/osdep.c b/osdep.c index 327583b..93bfbe0 100644 --- a/osdep.c +++ b/osdep.c @@ -147,6 +147,89 @@ int qemu_socket(int domain, int type, int protocol) return ret; } +#ifdef _WIN32 +int qemu_socketpair(int domain, int type, int protocol, int socks[2]) +{ + union { + struct sockaddr_in inaddr; + struct sockaddr addr; + } a; + int listener; + socklen_t addrlen = sizeof(a.inaddr); + int reuse = 1; + + if (domain == AF_UNIX) { + domain = AF_INET; + } + + if (socks == 0) { + return EINVAL; + } + + listener = qemu_socket(domain, type, protocol); + if (listener < 0) { + return listener; + } + + memset(&a, 0, sizeof(a)); + a.inaddr.sin_family = AF_INET; + a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.inaddr.sin_port = 0; + + socks[0] = socks[1] = -1; + + if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, + (char*) &reuse, (socklen_t) sizeof(reuse)) == -1) { + goto error; + } + if (bind(listener, &a.addr, sizeof(a.inaddr)) < 0) { + goto error; + } + + memset(&a, 0, sizeof(a)); + if (getsockname(listener, &a.addr, &addrlen) < 0) { + goto error; + } + + a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.inaddr.sin_family = AF_INET; + + if (listen(listener, 1) < 0) { + goto error; + } + + socks[0] = qemu_socket(AF_INET, SOCK_STREAM, 0); + if (socks[0] < 0) { + goto error; + } + if (connect(socks[0], &a.addr, sizeof(a.inaddr)) < 0) { + goto error; + } + + socks[1] = qemu_accept(listener, NULL, NULL); + if (socks[1] < 0) { + goto error; + } + + closesocket(listener); + return 0; + +error: + if (listener != -1) + closesocket(listener); + if (socks[0] != -1) + closesocket(socks[0]); + if (socks[1] != -1) + closesocket(socks[1]); + return -1; +} +#else +int qemu_socketpair(int domain, int type, int protocol, int socks[2]) +{ + return socketpair(domain, type, protocol, socks); +} +#endif + /* * Accept a connection and set FD_CLOEXEC */ diff --git a/qemu_socket.h b/qemu_socket.h index 180e4db..d7eb9a5 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -34,6 +34,7 @@ int inet_aton(const char *cp, struct in_addr *ia); /* misc helpers */ int qemu_socket(int domain, int type, int protocol); +int qemu_socketpair(int domain, int type, int protocol, int socks[2]); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); void socket_set_nonblock(int fd); int send_all(int fd, const void *buf, int len1); -- 1.7.3.4