From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=36955 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxfT0-00076q-5C for qemu-devel@nongnu.org; Thu, 10 Mar 2011 07:59:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PxfSz-00078S-2i for qemu-devel@nongnu.org; Thu, 10 Mar 2011 07:59:46 -0500 Received: from smtp3.tech.numericable.fr ([82.216.111.39]:41278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PxfSy-000786-N1 for qemu-devel@nongnu.org; Thu, 10 Mar 2011 07:59:45 -0500 From: Corentin Chary Date: Thu, 10 Mar 2011 13:59:38 +0100 Message-Id: <1299761979-15197-1-git-send-email-corentin.chary@gmail.com> In-Reply-To: <4D7767C0.6060609@siemens.com> References: <4D7767C0.6060609@siemens.com> Subject: [Qemu-devel] [PATCH 1/2] sockets: add qemu_socketpair() List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jan Kiszka Cc: kvm@vger.kernel.org, Peter Lieven , qemu-devel , Anthony Liguori , Corentin Chary , Paolo Bonzini Signed-off-by: Corentin Chary --- 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