From b5ebc513d199d184d85e405022cec4d2f7e98563 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 21 Apr 2016 16:58:47 -0400
Subject: [PATCH] Improve TranslateSocketError() to handle more Windows error
 codes.

The coverage was rather lean for cases that bind() or listen() might
return.  Add entries for everything that there's a direct equivalent
for in the set of Unix errnos that elog.c has heard of.
---
 src/backend/port/win32/socket.c | 55 ++++++++++++++++++++++++++-------
 src/include/port/win32.h        | 16 ++++++++--
 2 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c
index f82553fca64..2db5a7fe4aa 100644
--- a/src/backend/port/win32/socket.c
+++ b/src/backend/port/win32/socket.c
@@ -44,23 +44,38 @@ int			pgwin32_noblock = 0;
 
 /*
  * Convert the last socket error code into errno
+ *
+ * Note: where there is a direct correspondence between a WSAxxx error code
+ * and a Berkeley error symbol, this mapping is actually a no-op, because
+ * in win32.h we redefine the network-related Berkeley error symbols to have
+ * the values of their WSAxxx counterparts.  The point of the switch is
+ * mostly to translate near-miss error codes into something that's sensible
+ * in the Berkeley universe.
  */
 static void
 TranslateSocketError(void)
 {
 	switch (WSAGetLastError())
 	{
-		case WSANOTINITIALISED:
-		case WSAENETDOWN:
-		case WSAEINPROGRESS:
 		case WSAEINVAL:
-		case WSAESOCKTNOSUPPORT:
-		case WSAEFAULT:
+		case WSANOTINITIALISED:
 		case WSAEINVALIDPROVIDER:
 		case WSAEINVALIDPROCTABLE:
-		case WSAEMSGSIZE:
+		case WSAEDESTADDRREQ:
 			errno = EINVAL;
 			break;
+		case WSAEINPROGRESS:
+			errno = EINPROGRESS;
+			break;
+		case WSAEFAULT:
+			errno = EFAULT;
+			break;
+		case WSAEISCONN:
+			errno = EISCONN;
+			break;
+		case WSAEMSGSIZE:
+			errno = EMSGSIZE;
+			break;
 		case WSAEAFNOSUPPORT:
 			errno = EAFNOSUPPORT;
 			break;
@@ -72,16 +87,23 @@ TranslateSocketError(void)
 			break;
 		case WSAEPROTONOSUPPORT:
 		case WSAEPROTOTYPE:
+		case WSAESOCKTNOSUPPORT:
 			errno = EPROTONOSUPPORT;
 			break;
+		case WSAECONNABORTED:
+			errno = ECONNABORTED;
+			break;
 		case WSAECONNREFUSED:
 			errno = ECONNREFUSED;
 			break;
+		case WSAECONNRESET:
+			errno = ECONNRESET;
+			break;
 		case WSAEINTR:
 			errno = EINTR;
 			break;
 		case WSAENOTSOCK:
-			errno = EBADFD;
+			errno = ENOTSOCK;
 			break;
 		case WSAEOPNOTSUPP:
 			errno = EOPNOTSUPP;
@@ -92,13 +114,24 @@ TranslateSocketError(void)
 		case WSAEACCES:
 			errno = EACCES;
 			break;
-		case WSAENOTCONN:
+		case WSAEADDRINUSE:
+			errno = EADDRINUSE;
+			break;
+		case WSAEADDRNOTAVAIL:
+			errno = EADDRNOTAVAIL;
+			break;
+		case WSAEHOSTUNREACH:
+		case WSAEHOSTDOWN:
+		case WSAHOST_NOT_FOUND:
+		case WSAENETDOWN:
+		case WSAENETUNREACH:
 		case WSAENETRESET:
-		case WSAECONNRESET:
+			errno = EHOSTUNREACH;
+			break;
+		case WSAENOTCONN:
 		case WSAESHUTDOWN:
-		case WSAECONNABORTED:
 		case WSAEDISCON:
-			errno = ECONNREFUSED;		/* ENOTCONN? */
+			errno = ENOTCONN;
 			break;
 		default:
 			ereport(NOTICE,
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 0a978930314..6c56cc66b75 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -283,20 +283,32 @@ typedef int pid_t;
 #define EAFNOSUPPORT WSAEAFNOSUPPORT
 #undef EWOULDBLOCK
 #define EWOULDBLOCK WSAEWOULDBLOCK
+#undef ECONNABORTED
+#define ECONNABORTED WSAECONNABORTED
 #undef ECONNRESET
 #define ECONNRESET WSAECONNRESET
 #undef EINPROGRESS
 #define EINPROGRESS WSAEINPROGRESS
+#undef EISCONN
+#define EISCONN WSAEISCONN
 #undef ENOBUFS
 #define ENOBUFS WSAENOBUFS
 #undef EPROTONOSUPPORT
 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
 #undef ECONNREFUSED
 #define ECONNREFUSED WSAECONNREFUSED
-#undef EBADFD
-#define EBADFD WSAENOTSOCK
+#undef ENOTSOCK
+#define ENOTSOCK WSAENOTSOCK
 #undef EOPNOTSUPP
 #define EOPNOTSUPP WSAEOPNOTSUPP
+#undef EADDRINUSE
+#define EADDRINUSE WSAEADDRINUSE
+#undef EADDRNOTAVAIL
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#undef EHOSTUNREACH
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#undef ENOTCONN
+#define ENOTCONN WSAENOTCONN
 
 /*
  * Extended locale functions with gratuitous underscore prefixes.
-- 
GitLab