From d1b7d4877b9a71f476e8e5adea3b6afe419896ba Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 12 Apr 2016 19:52:21 -0400
Subject: [PATCH] Provide errno-translation wrappers around bind() and listen()
 on Windows.

I've seen one too many "could not bind IPv4 socket: No error" log entries
from the Windows buildfarm members.  Per previous discussion, this is
likely caused by the fact that we're doing nothing to translate
WSAGetLastError() to errno.  Put in a wrapper layer to do that.

If this works as expected, it should get back-patched, but let's see what
happens in the buildfarm first.

Discussion: <4065.1452450340@sss.pgh.pa.us>
---
 src/backend/port/win32/socket.c | 24 ++++++++++++++++++++++++
 src/include/port/win32.h        |  4 ++++
 2 files changed, 28 insertions(+)

diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c
index 747304cee42..ea4fb557b6e 100644
--- a/src/backend/port/win32/socket.c
+++ b/src/backend/port/win32/socket.c
@@ -27,7 +27,10 @@
  */
 int			pgwin32_noblock = 0;
 
+/* Undef the macros defined in win32.h, so we can access system functions */
 #undef socket
+#undef bind
+#undef listen
 #undef accept
 #undef connect
 #undef select
@@ -261,6 +264,27 @@ pgwin32_socket(int af, int type, int protocol)
 	return s;
 }
 
+int
+pgwin32_bind(SOCKET s, struct sockaddr * addr, int *addrlen)
+{
+	int			res;
+
+	res = bind(s, addr, addrlen);
+	if (res < 0)
+		TranslateSocketError();
+	return res;
+}
+
+int
+pgwin32_listen(SOCKET s, int backlog)
+{
+	int			res;
+
+	res = listen(s, backlog);
+	if (res < 0)
+		TranslateSocketError();
+	return res;
+}
 
 SOCKET
 pgwin32_accept(SOCKET s, struct sockaddr * addr, int *addrlen)
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 69cd1c41e15..9810a835401 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -364,6 +364,8 @@ void		pg_queue_signal(int signum);
 /* In backend/port/win32/socket.c */
 #ifndef FRONTEND
 #define socket(af, type, protocol) pgwin32_socket(af, type, protocol)
+#define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen)
+#define listen(s, backlog) pgwin32_listen(s, backlog)
 #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen)
 #define connect(s, name, namelen) pgwin32_connect(s, name, namelen)
 #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
@@ -371,6 +373,8 @@ void		pg_queue_signal(int signum);
 #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags)
 
 SOCKET		pgwin32_socket(int af, int type, int protocol);
+int			pgwin32_bind(SOCKET s, struct sockaddr * addr, int *addrlen);
+int			pgwin32_listen(SOCKET s, int backlog);
 SOCKET		pgwin32_accept(SOCKET s, struct sockaddr * addr, int *addrlen);
 int			pgwin32_connect(SOCKET s, const struct sockaddr * name, int namelen);
 int			pgwin32_select(int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval * timeout);
-- 
GitLab