summaryrefslogtreecommitdiff
path: root/src/interfaces
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-04-24 02:26:06 +0000
committerBruce Momjian <bruce@momjian.us>2002-04-24 02:26:06 +0000
commit30571b549675ea8dfab2aeeb65eaf607072e86e1 (patch)
tree882db49faf84c816e6975e90a30ade765ff4c2bf /src/interfaces
parentdd4ca824cc91f0c3156d4ed9774b03005d9580e0 (diff)
downloadpostgresql-30571b549675ea8dfab2aeeb65eaf607072e86e1.tar.gz
I'm at the win32 error messages once more. The DLL load thingy doesn't
work on all win9x machines, so i made it go thru a l ookup table instead, using the DLL as last resort. I also moved this out of the fe-misc.c file because of the size of the lookup ta ble. Who knows, we might add more other win32 specific code there in the future. I also fixed a small typo in the pg_config.h.win32 that made the compiler compla in about the gnu snprintf declaration. I tried to make this patch with psql coding style. I've successfully tested this on win2k and win98 and it works fine (i.e. the mes sage shows on win98 too, it didn't with the old implementation). Magnus Naeslund
Diffstat (limited to 'src/interfaces')
-rw-r--r--src/interfaces/libpq/fe-misc.c47
-rw-r--r--src/interfaces/libpq/win32.c182
-rw-r--r--src/interfaces/libpq/win32.mak7
3 files changed, 187 insertions, 49 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 190d378fd9..643c81055f 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -25,7 +25,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.70 2002/04/24 02:26:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,8 +37,6 @@
#include <time.h>
#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
#include "win32.h"
#else
#include <unistd.h>
@@ -894,46 +892,3 @@ libpq_gettext(const char *msgid)
return dgettext("libpq", msgid);
}
#endif /* ENABLE_NLS */
-
-#ifdef WIN32
-/*
- * strerror replacement for windows:
- *
- * This works on WIN2000 and newer, but we don't know where to find WinSock
- * error strings on older Windows flavors. If you know, clue us in.
- */
-const char *
-winsock_strerror(int eno)
-{
- static char err_buf[512];
-#define WSSE_MAXLEN (sizeof(err_buf)-1-13) /* 13 for " (0x00000000)" */
- int length;
-
- /* First try the "system table", this works on Win2k and up */
-
- if (FormatMessage(
- FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
- 0,
- eno,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- err_buf,
- WSSE_MAXLEN,
- NULL))
- goto WSSE_GOODEXIT;
-
- /* Insert other possible lookup methods here ... */
-
- /* Everything failed, just tell the user that we don't know the desc */
-
- strcpy(err_buf, "Socket error, no description available.");
-
-WSSE_GOODEXIT:
-
- length = strlen(err_buf);
- sprintf(err_buf + (length < WSSE_MAXLEN ? length : WSSE_MAXLEN),
- " (0x%08X)", eno);
-
- return err_buf;
-}
-
-#endif
diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c
new file mode 100644
index 0000000000..9c7d379456
--- /dev/null
+++ b/src/interfaces/libpq/win32.c
@@ -0,0 +1,182 @@
+/*
+ * FILE
+ * win32.c
+ *
+ * DESCRIPTION
+ * Win32 support functions.
+ *
+ * Contains table and functions for looking up win32 socket error
+ * descriptions. But will/may contain other win32 helper functions
+ * for libpq.
+ *
+ * The error constants are taken from the Frambak Bakfram LGSOCKET
+ * library guys who in turn took them from the Winsock FAQ.
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock.h>
+#include <stdio.h>
+#include "win32.h"
+
+static struct WSErrorEntry {
+ DWORD error;
+ const char* description;
+} WSErrors [] = {
+ {0, "No error"},
+ {WSAEINTR, "Interrupted system call"},
+ {WSAEBADF, "Bad file number"},
+ {WSAEACCES, "Permission denied"},
+ {WSAEFAULT, "Bad address"},
+ {WSAEINVAL, "Invalid argument"},
+ {WSAEMFILE, "Too many open sockets"},
+ {WSAEWOULDBLOCK, "Operation would block"},
+ {WSAEINPROGRESS, "Operation now in progress"},
+ {WSAEALREADY, "Operation already in progress"},
+ {WSAENOTSOCK, "Socket operation on non-socket"},
+ {WSAEDESTADDRREQ, "Destination address required"},
+ {WSAEMSGSIZE, "Message too long"},
+ {WSAEPROTOTYPE, "Protocol wrong type for socket"},
+ {WSAENOPROTOOPT, "Bad protocol option"},
+ {WSAEPROTONOSUPPORT, "Protocol not supported"},
+ {WSAESOCKTNOSUPPORT, "Socket type not supported"},
+ {WSAEOPNOTSUPP, "Operation not supported on socket"},
+ {WSAEPFNOSUPPORT, "Protocol family not supported"},
+ {WSAEAFNOSUPPORT, "Address family not supported"},
+ {WSAEADDRINUSE, "Address already in use"},
+ {WSAEADDRNOTAVAIL, "Can't assign requested address"},
+ {WSAENETDOWN, "Network is down"},
+ {WSAENETUNREACH, "Network is unreachable"},
+ {WSAENETRESET, "Net connection reset"},
+ {WSAECONNABORTED, "Software caused connection abort"},
+ {WSAECONNRESET, "Connection reset by peer"},
+ {WSAENOBUFS, "No buffer space available"},
+ {WSAEISCONN, "Socket is already connected"},
+ {WSAENOTCONN, "Socket is not connected"},
+ {WSAESHUTDOWN, "Can't send after socket shutdown"},
+ {WSAETOOMANYREFS, "Too many references, can't splice"},
+ {WSAETIMEDOUT, "Connection timed out"},
+ {WSAECONNREFUSED, "Connection refused"},
+ {WSAELOOP, "Too many levels of symbolic links"},
+ {WSAENAMETOOLONG, "File name too long"},
+ {WSAEHOSTDOWN, "Host is down"},
+ {WSAEHOSTUNREACH, "No route to host"},
+ {WSAENOTEMPTY, "Directory not empty"},
+ {WSAEPROCLIM, "Too many processes"},
+ {WSAEUSERS, "Too many users"},
+ {WSAEDQUOT, "Disc quota exceeded"},
+ {WSAESTALE, "Stale NFS file handle"},
+ {WSAEREMOTE, "Too many levels of remote in path"},
+ {WSASYSNOTREADY, "Network system is unavailable"},
+ {WSAVERNOTSUPPORTED, "Winsock version out of range"},
+ {WSANOTINITIALISED, "WSAStartup not yet called"},
+ {WSAEDISCON, "Graceful shutdown in progress"},
+ {WSAHOST_NOT_FOUND, "Host not found"},
+ {WSATRY_AGAIN, "NA Host not found / SERVFAIL"},
+ {WSANO_RECOVERY, "Non recoverable FORMERR||REFUSED||NOTIMP"},
+ {WSANO_DATA, "No host data of that type was found"},
+ {0,0} /* End of table */
+};
+
+
+/*
+ * Returns 0 if not found, linear but who cares, at this moment
+ * we're already in pain :)
+ */
+
+static int LookupWSErrorMessage(DWORD err,char*dest)
+{
+ struct WSErrorEntry *e;
+ for (e = WSErrors;e->description;e++)
+ {
+ if (e->error == err)
+ {
+ strcpy(dest,e->description);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+struct MessageDLL{
+ const char *dll_name;
+ void *handle;
+ int loaded; /* BOOL */
+}dlls[]={
+ {"netmsg.dll",0,0},
+ {"winsock.dll",0,0},
+ {"wsock32.dll",0,0},
+ {"ws2_32.dll",0,0},
+ {"wsock32n.dll",0,0},
+ {"mswsock.dll",0,0},
+ {"ws2help.dll",0,0},
+ {"ws2thk.dll",0,0},
+ {0,0,1} /* Last one, no dll, always loaded */
+};
+
+#define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL))
+
+/*
+ * Returns a description of the socket error by first trying
+ * to find it in the lookup table, and if that fails, tries
+ * to load any of the winsock dlls to find that message.
+ * The DLL thing works from Nt4 (spX ?) up, but some special
+ * versions of winsock might have this aswell (seen on Win98 SE
+ * special install) / Magnus Naeslund (mag@fbab.net)
+ *
+ */
+
+const char *winsock_strerror(int err){
+ static char buf[512]; /* Not threadsafe */
+ unsigned long flags;
+ int offs,i;
+ int success = LookupWSErrorMessage(err,buf);
+
+ for (i=0;!success && i<DLLS_SIZE;i++)
+ {
+
+ if (!dlls[i].loaded)
+ {
+ dlls[i].loaded = 1; /* Only load once */
+ dlls[i].handle = (void*)LoadLibraryEx(
+ dlls[i].dll_name,
+ 0,
+ LOAD_LIBRARY_AS_DATAFILE);
+ }
+
+ if (dlls[i].dll_name && !dlls[i].handle)
+ continue; /* Didn't load */
+
+ flags = FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | (dlls[i].handle?FORMAT_MESSAGE_FROM_HMODULE:0);
+
+ success = 0 != FormatMessage(
+ flags,
+ dlls[i].handle,err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buf,sizeof(buf)-64,
+ 0
+ );
+ }
+
+ if (!success)
+ {
+ sprintf(buf,"Unknown socket error (0x%08X/%lu)",err,err);
+ }
+ else
+ {
+ buf[sizeof(buf)-1]='\0';
+ offs = strlen(buf);
+ if (offs>sizeof(buf)-64)
+ offs = sizeof(buf)-64;
+ sprintf(buf+offs," (0x%08X/%lu)",err,err);
+ }
+ return buf;
+}
+
diff --git a/src/interfaces/libpq/win32.mak b/src/interfaces/libpq/win32.mak
index ea433eafac..98b4e986ef 100644
--- a/src/interfaces/libpq/win32.mak
+++ b/src/interfaces/libpq/win32.mak
@@ -64,6 +64,7 @@ CLEAN :
-@erase "$(INTDIR)\fe-print.obj"
-@erase "$(INTDIR)\pqexpbuffer.obj"
-@erase "$(OUTDIR)\libpqdll.obj"
+ -@erase "$(OUTDIR)\win32.obj"
-@erase "$(OUTDIR)\libpq.lib"
-@erase "$(OUTDIR)\libpq.dll"
-@erase "$(OUTDIR)\libpq.res"
@@ -96,6 +97,7 @@ CPP_SBRS=.
LIB32=link.exe -lib
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\libpq.lib"
LIB32_OBJS= \
+ "$(OUTDIR)\win32.obj" \
"$(INTDIR)\dllist.obj" \
"$(INTDIR)\md5.obj" \
"$(INTDIR)\fe-auth.obj" \
@@ -113,9 +115,8 @@ LIB32_OBJS = $(LIB32_OBJS) "$(INTDIR)\wchar.obj" "$(INTDIR)\encnames.obj"
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libpq.res"
LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib wsock32.lib\
- odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
+LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib wsock32.lib\
+ /nologo /subsystem:windows /dll /incremental:no\
/pdb:"$(OUTDIR)\libpqdll.pdb" /machine:I386 /out:"$(OUTDIR)\libpq.dll"\
/implib:"$(OUTDIR)\libpqdll.lib" /def:libpqdll.def
LINK32_OBJS= \