2 * src/interfaces/libpq/win32.c
9 * Win32 support functions.
11 * Contains table and functions for looking up win32 socket error
12 * descriptions. But will/may contain other win32 helper functions
15 * The error constants are taken from the Frambak Bakfram LGSOCKET
16 * library guys who in turn took them from the Winsock FAQ.
18 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
19 * Portions Copyright (c) 1994, Regents of the University of California
23 /* Make stuff compile faster by excluding not used stuff */
31 #include "postgres_fe.h"
35 /* Declared here to avoid pulling in all includes, which causes name collissions */
38 libpq_gettext(const char *msgid)
39 __attribute__((format_arg(1)));
41 #define libpq_gettext(x) (x)
45 static struct WSErrorEntry
48 const char *description;
56 WSAEINTR, "Interrupted system call"
59 WSAEBADF, "Bad file number"
62 WSAEACCES, "Permission denied"
65 WSAEFAULT, "Bad address"
68 WSAEINVAL, "Invalid argument"
71 WSAEMFILE, "Too many open sockets"
74 WSAEWOULDBLOCK, "Operation would block"
77 WSAEINPROGRESS, "Operation now in progress"
80 WSAEALREADY, "Operation already in progress"
83 WSAENOTSOCK, "Socket operation on non-socket"
86 WSAEDESTADDRREQ, "Destination address required"
89 WSAEMSGSIZE, "Message too long"
92 WSAEPROTOTYPE, "Protocol wrong type for socket"
95 WSAENOPROTOOPT, "Bad protocol option"
98 WSAEPROTONOSUPPORT, "Protocol not supported"
101 WSAESOCKTNOSUPPORT, "Socket type not supported"
104 WSAEOPNOTSUPP, "Operation not supported on socket"
107 WSAEPFNOSUPPORT, "Protocol family not supported"
110 WSAEAFNOSUPPORT, "Address family not supported"
113 WSAEADDRINUSE, "Address already in use"
116 WSAEADDRNOTAVAIL, "Cannot assign requested address"
119 WSAENETDOWN, "Network is down"
122 WSAENETUNREACH, "Network is unreachable"
125 WSAENETRESET, "Net connection reset"
128 WSAECONNABORTED, "Software caused connection abort"
131 WSAECONNRESET, "Connection reset by peer"
134 WSAENOBUFS, "No buffer space available"
137 WSAEISCONN, "Socket is already connected"
140 WSAENOTCONN, "Socket is not connected"
143 WSAESHUTDOWN, "Cannot send after socket shutdown"
146 WSAETOOMANYREFS, "Too many references, cannot splice"
149 WSAETIMEDOUT, "Connection timed out"
152 WSAECONNREFUSED, "Connection refused"
155 WSAELOOP, "Too many levels of symbolic links"
158 WSAENAMETOOLONG, "File name too long"
161 WSAEHOSTDOWN, "Host is down"
164 WSAEHOSTUNREACH, "No route to host"
167 WSAENOTEMPTY, "Directory not empty"
170 WSAEPROCLIM, "Too many processes"
173 WSAEUSERS, "Too many users"
176 WSAEDQUOT, "Disc quota exceeded"
179 WSAESTALE, "Stale NFS file handle"
182 WSAEREMOTE, "Too many levels of remote in path"
185 WSASYSNOTREADY, "Network system is unavailable"
188 WSAVERNOTSUPPORTED, "Winsock version out of range"
191 WSANOTINITIALISED, "WSAStartup not yet called"
194 WSAEDISCON, "Graceful shutdown in progress"
197 WSAHOST_NOT_FOUND, "Host not found"
200 WSATRY_AGAIN, "NA Host not found / SERVFAIL"
203 WSANO_RECOVERY, "Non recoverable FORMERR||REFUSED||NOTIMP"
206 WSANO_DATA, "No host data of that type was found"
215 * Returns 0 if not found, linear but who cares, at this moment
216 * we're already in pain :)
220 LookupWSErrorMessage(DWORD err, char *dest)
222 struct WSErrorEntry *e;
224 for (e = WSErrors; e->description; e++)
228 strcpy(dest, e->description);
238 const char *dll_name;
240 int loaded; /* BOOL */
270 } /* Last one, no dll, always loaded */
273 #define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL))
276 * Returns a description of the socket error by first trying
277 * to find it in the lookup table, and if that fails, tries
278 * to load any of the winsock dlls to find that message.
279 * The DLL thing works from Nt4 (spX ?) up, but some special
280 * versions of winsock might have this as well (seen on Win98 SE
281 * special install) / Magnus Naeslund (mag@fbab.net)
286 winsock_strerror(int err, char *strerrbuf, size_t buflen)
291 int success = LookupWSErrorMessage(err, strerrbuf);
293 for (i = 0; !success && i < DLLS_SIZE; i++)
298 dlls[i].loaded = 1; /* Only load once */
299 dlls[i].handle = (void *) LoadLibraryEx(
302 LOAD_LIBRARY_AS_DATAFILE);
305 if (dlls[i].dll_name && !dlls[i].handle)
306 continue; /* Didn't load */
308 flags = FORMAT_MESSAGE_FROM_SYSTEM
309 | FORMAT_MESSAGE_IGNORE_INSERTS
310 | (dlls[i].handle ? FORMAT_MESSAGE_FROM_HMODULE : 0);
312 success = 0 != FormatMessage(
315 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
316 strerrbuf, buflen - 64,
322 sprintf(strerrbuf, libpq_gettext("unrecognized socket error: 0x%08X/%d"), err, err);
325 strerrbuf[buflen - 1] = '\0';
326 offs = strlen(strerrbuf);
327 if (offs > (int) buflen - 64)
329 sprintf(strerrbuf + offs, " (0x%08X/%d)", err, err);