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
This commit is contained in:
Bruce Momjian 2002-04-24 02:26:06 +00:00
parent dd4ca824cc
commit 30571b5496
4 changed files with 188 additions and 50 deletions

View File

@ -28,7 +28,7 @@
#define HAVE_NAMESPACE_STD
/* use _snprintf instead of snprintf */
#define HAVE_SNPRINTF_DECL
#define HAVE_DECL_SNPRINTF 1
#define snprintf _snprintf
/* defines for dynamic linking on Win32 platform */

View File

@ -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

View File

@ -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;
}

View File

@ -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= \