From 6ab3bf380e7c4f2b7b49b2174f393f6924c7b70d Mon Sep 17 00:00:00 2001
From: Stefan Weil <sw@weilnetz.de>
Date: Wed, 4 Sep 2013 22:43:19 +0200
Subject: [PATCH 4/7] w32: Fix handling of SO_REUSEADDR

Signed-off-by: Stefan Weil <sw@weilnetz.de>
---
 bt-host.c              |    1 +
 include/qemu-common.h  |   19 -------------------
 include/qemu/sockets.h |   20 ++++++++++++++++++++
 linux-user/syscall.c   |    1 +
 util/oslib-win32.c     |   16 ++++++++++++++++
 5 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/bt-host.c b/bt-host.c
index 49205bf..839e2c0 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -20,6 +20,7 @@
 #include "qemu-common.h"
 #include "sysemu/bt.h"
 #include "qemu/main-loop.h"
+#include "qemu/sockets.h"
 
 #ifndef _WIN32
 # include <errno.h>
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 6948bb9..78bfc30 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -226,25 +226,6 @@ int qemu_pipe(int pipefd[2]);
 int qemu_openpty_raw(int *aslave, char *pty_name);
 #endif
 
-#ifdef _WIN32
-/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
-#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
-    getsockopt(sockfd, level, optname, (void *)optval, optlen)
-#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
-    setsockopt(sockfd, level, optname, (const void *)optval, optlen)
-#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
-#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
-    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
-#else
-#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
-    getsockopt(sockfd, level, optname, optval, optlen)
-#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
-    setsockopt(sockfd, level, optname, optval, optlen)
-#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
-#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
-    sendto(sockfd, buf, len, flags, destaddr, addrlen)
-#endif
-
 /* Error handling.  */
 
 void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index c5174d7..7346585 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -42,6 +42,26 @@ void qemu_set_nonblock(int fd);
 int send_all(int fd, const void *buf, int len1);
 int recv_all(int fd, void *buf, int len1, bool single_read);
 
+int qemu_getsockopt(int sockfd, int level, int optname,
+                    void *optval, socklen_t *optlen);
+int qemu_setsockopt(int sockfd, int level, int optname,
+                    const void *optval, socklen_t optlen);
+
+#ifdef _WIN32
+/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
+#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
+#else
+#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
+    getsockopt(sockfd, level, optname, optval, optlen)
+#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
+    setsockopt(sockfd, level, optname, optval, optlen)
+#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, buf, len, flags, destaddr, addrlen)
+#endif
+
 /* callback function for nonblocking connect
  * valid fd on success, negative error code on failure
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ecead51..5713efd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -66,6 +66,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <linux/wireless.h>
 #include <linux/icmp.h>
 #include "qemu-common.h"
+#include "qemu/sockets.h"
 #ifdef TARGET_GPROF
 #include <sys/gmon.h>
 #endif
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 961fbf5..5587694 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -161,6 +161,22 @@ int qemu_gettimeofday(qemu_timeval *tp)
   return 0;
 }
 
+int qemu_getsockopt(int sockfd, int level, int optname,
+                    void *optval, socklen_t *optlen)
+{
+    return getsockopt(sockfd, level, optname, optval, optlen);
+}
+
+int qemu_setsockopt(int sockfd, int level, int optname,
+                    const void *optval, socklen_t optlen)
+{
+    int res = 0;
+    if (optname != SO_REUSEADDR) {
+        res = setsockopt(sockfd, level, optname, optval, optlen);
+    }
+    return res;
+}
+
 int qemu_get_thread_id(void)
 {
     return GetCurrentThreadId();
-- 
1.7.10.4

