From 61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 27 Oct 2008 16:07:50 +0000 Subject: david - apparently windows prefers to dynamically load winsock and a couple other libraries, so I got it all compiling and working in windows, yay!... I tried to minimize the impact on the code: I made a DYNLOAD macro that evaluates to nothing on everything else, but runs the dynamic code if compiled for windows... also, apparently I had been randomly switching between ifdef and ifndef WIN32: so i made most of them ifdefs so it was less confusing... --- buildMinGW.conf | 2 +- src/serversocket.cpp | 47 +++++--- src/socket.cpp | 90 +++++++++------ src/win32_compatibility.cpp | 266 ++++++++++++++++++++++++++++++++++++++++++++ src/win32_compatibility.h | 33 +++++- 5 files changed, 383 insertions(+), 55 deletions(-) create mode 100644 src/win32_compatibility.cpp diff --git a/buildMinGW.conf b/buildMinGW.conf index ec8c421..fe00254 100644 --- a/buildMinGW.conf +++ b/buildMinGW.conf @@ -22,7 +22,7 @@ filesIn("src") filter regexp("^src/(.*)\\.h$", "bu/{re:1}.h"): target file, set "CXXFLAGS" += "-I.", #input filesIn("src") filter regexp("^.*\\.cpp$") - input ["src/list.cpp", "src/exceptionbase.cpp", "src/fstring.cpp", "src/file.cpp", "src/hash.cpp", "src/sptr.cpp", "src/tafnode.cpp", "src/tafreader.cpp", "src/tafwriter.cpp", "src/stdstream.cpp", "src/stream.cpp", "src/archive.cpp", "src/archival.cpp", "src/socket.cpp", "src/serversocket.cpp"] + input ["src/list.cpp", "src/exceptionbase.cpp", "src/fstring.cpp", "src/file.cpp", "src/set.cpp", "src/hash.cpp", "src/sptr.cpp", "src/tafnode.cpp", "src/tafreader.cpp", "src/tafwriter.cpp", "src/stdstream.cpp", "src/stream.cpp", "src/archive.cpp", "src/archival.cpp", "src/socket.cpp", "src/serversocket.cpp", "src/unitsuite.cpp", "src/win32_compatibility.cpp"] rule "exe": matches regexp("(.*)\\.win_o$"), diff --git a/src/serversocket.cpp b/src/serversocket.cpp index 5ed661e..1908a8a 100644 --- a/src/serversocket.cpp +++ b/src/serversocket.cpp @@ -35,11 +35,11 @@ Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) : /* Give the socket a name. */ name.sin_family = AF_INET; - name.sin_port = htons( nPort ); + name.sin_port = DYNLOAD htons( nPort ); // I think this specifies who we will accept connections from, // a good thing to make configurable later on - name.sin_addr.s_addr = htonl( INADDR_ANY ); + name.sin_addr.s_addr = DYNLOAD htonl( INADDR_ANY ); startServer( name, nPoolSize ); } @@ -52,10 +52,11 @@ Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) : /* Give the socket a name. */ name.sin_family = AF_INET; - name.sin_port = htons( nPort ); + + name.sin_port = DYNLOAD htons( nPort ); #ifdef WIN32 - name.sin_addr.s_addr = inet_addr( sAddr.getStr() ); + name.sin_addr.s_addr = DYNLOAD inet_addr( sAddr.getStr() ); #else inet_aton( sAddr.getStr(), &name.sin_addr ); #endif @@ -70,27 +71,29 @@ Bu::ServerSocket::~ServerSocket() void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) { /* Create the socket. */ - nServer = socket( PF_INET, SOCK_STREAM, 0 ); + nServer = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); + if( nServer < 0 ) { throw Bu::ServerSocketException("Couldn't create a listen socket."); } int opt = 1; - setsockopt( - nServer, - SOL_SOCKET, - SO_REUSEADDR, - (char *)&opt, - sizeof( opt ) - ); - - if( bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) + DYNLOAD setsockopt( + nServer, + SOL_SOCKET, + SO_REUSEADDR, + (char *)&opt, + sizeof( opt ) + ); + + if( DYNLOAD bind( + nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) { throw Bu::ServerSocketException("Couldn't bind to the listen socket."); } - if( listen( nServer, nPoolSize ) < 0 ) + if( DYNLOAD listen( nServer, nPoolSize ) < 0 ) { throw Bu::ServerSocketException( "Couldn't begin listening to the server socket." @@ -116,20 +119,29 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) xT.tv_sec = nTimeoutSec; xT.tv_usec = nTimeoutUSec; - if( TEMP_FAILURE_RETRY(select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) + if( TEMP_FAILURE_RETRY( + DYNLOAD select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) { throw Bu::ServerSocketException( "Error scanning for new connections: %s", strerror( errno ) ); } +#ifdef WIN32 + if( DynamicWinsock2::DYN_FD_ISSET( nServer, &fdRead ) ) +#else if( FD_ISSET( nServer, &fdRead ) ) +#endif { struct sockaddr_in clientname; socklen_t size; int nClient; size = sizeof( clientname ); +#ifdef WIN32 + nClient = DYNLOAD accept( + nServer, (struct sockaddr *)&clientname, (int *)&size); +#else /* not-WIN32 */ #ifdef __CYGWIN__ nClient = ::accept( nServer, (struct sockaddr *)&clientname, (int *)&size @@ -141,6 +153,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size ); #endif /* __APPLE__ */ #endif /* __CYGWIN__ */ +#endif /* WIN32 */ if( nClient < 0 ) { throw Bu::ServerSocketException( @@ -175,7 +188,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) // If iMode = 0, blocking is enabled; // If iMode != 0, non-blocking mode is enabled. u_long iMode = 1; - ioctlsocket(nClient, FIONBIO, &iMode); + DYNLOAD ioctlsocket(nClient, FIONBIO, &iMode); #endif } diff --git a/src/socket.cpp b/src/socket.cpp index aea66f8..ce16794 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -44,7 +44,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) bActive = false; /* Create the socket. */ - nSocket = socket( PF_INET, SOCK_STREAM, 0 ); + nSocket = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); if( nSocket < 0 ) { @@ -68,7 +68,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) // If iMode = 0, blocking is enabled; // If iMode != 0, non-blocking mode is enabled. u_long iMode = 1; - ioctlsocket(nSocket, FIONBIO, &iMode); + DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); #endif /* Connect to the server. */ @@ -77,8 +77,8 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) struct hostent *hostinfo; xServerName.sin_family = AF_INET; - xServerName.sin_port = htons( nPort ); - hostinfo = gethostbyname( sAddr.getStr() ); + xServerName.sin_port = DYNLOAD htons( nPort ); + hostinfo = DYNLOAD gethostbyname( sAddr.getStr() ); if (hostinfo == NULL) { throw Bu::SocketException("Couldn't resolve hostname.\n"); @@ -88,7 +88,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) //printf("Making actual connection..."); //fflush( stdout ); - connect( + DYNLOAD connect( nSocket, (struct sockaddr *)&xServerName, sizeof(xServerName) @@ -113,7 +113,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) tv.tv_sec = nTimeout; tv.tv_usec = 0; - retval = select( nSocket+1, &rfds, &wfds, &efds, &tv ); + retval = DYNLOAD select( nSocket+1, &rfds, &wfds, &efds, &tv ); if( retval == 0 ) { @@ -195,7 +195,12 @@ void Bu::Socket::read() size_t Bu::Socket::read( void *pBuf, size_t nBytes ) { +#ifdef WIN32 + int nRead = TEMP_FAILURE_RETRY( + DYNLOAD recv( nSocket, (char *) pBuf, nBytes, 0 ) ); +#else int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); +#endif if( nRead < 0 ) { throw SocketException( SocketException::cRead, strerror(errno) ); @@ -213,35 +218,35 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, FD_ZERO(&rfds); FD_SET(nSocket, &rfds); -#ifndef WIN32 +#ifdef WIN32 + DWORD dwStart = GetTickCount(); + uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); + DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; +#else struct timeval nt, ct; gettimeofday( &nt, NULL ); nt.tv_sec += nSec; nt.tv_usec += nUSec; -#else - DWORD dwStart = GetTickCount(); - uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); - DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; #endif for(;;) { tv.tv_sec = nSec; tv.tv_usec = nUSec; - select( nSocket+1, &rfds, NULL, NULL, &tv ); + DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); if( nRead >= nBytes ) break; -#ifndef WIN32 +#ifdef WIN32 + DWORD dwNow = GetTickCount(); + if( dwNow > dwEnd ) + break; +#else gettimeofday( &ct, NULL ); if( (ct.tv_sec > nt.tv_sec) || (ct.tv_sec == nt.tv_sec && ct.tv_usec >= nt.tv_usec) ) break; -#else - DWORD dwNow = GetTickCount(); - if( dwNow > dwEnd ) - break; #endif } return nRead; @@ -249,7 +254,12 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) { +#ifdef WIN32 + int nWrote = TEMP_FAILURE_RETRY( + DYNLOAD send( nSocket, (const char *) pBuf, nBytes, 0 ) ); +#else int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); +#endif if( nWrote < 0 ) { if( errno == EAGAIN ) return 0; @@ -267,35 +277,35 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32 FD_ZERO(&wfds); FD_SET(nSocket, &wfds); -#ifndef WIN32 +#ifdef WIN32 + DWORD dwStart = GetTickCount(); + uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); + DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; +#else struct timeval nt, ct; gettimeofday( &nt, NULL ); nt.tv_sec += nSec; nt.tv_usec += nUSec; -#else - DWORD dwStart = GetTickCount(); - uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); - DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; #endif for(;;) { tv.tv_sec = nSec; tv.tv_usec = nUSec; - select( nSocket+1, NULL, &wfds, NULL, &tv ); + DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); if( nWrote >= nBytes ) break; -#ifndef WIN32 +#ifdef WIN32 + DWORD dwNow = GetTickCount(); + if( dwNow > dwEnd ) + break; +#else gettimeofday( &ct, NULL ); if( (ct.tv_sec > nt.tv_sec) || (ct.tv_sec == nt.tv_sec && ct.tv_usec >= nt.tv_usec) ) break; -#else - DWORD dwNow = GetTickCount(); - if( dwNow > dwEnd ) - break; #endif } return nWrote; @@ -332,13 +342,17 @@ bool Bu::Socket::canRead() FD_ZERO(&rfds); FD_SET(nSocket, &rfds); struct timeval tv = { 0, 0 }; - int retval = select( nSocket+1, &rfds, NULL, NULL, &tv ); + int retval = DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); if( retval == -1 ) throw SocketException( SocketException::cBadRead, "Bad Read error" ); +#ifdef WIN32 + if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &rfds ) ) +#else if( !FD_ISSET( nSocket, &rfds ) ) +#endif return false; return true; } @@ -349,13 +363,17 @@ bool Bu::Socket::canWrite() FD_ZERO(&wfds); FD_SET(nSocket, &wfds); struct timeval tv = { 0, 0 }; - int retval = select( nSocket+1, NULL, &wfds, NULL, &tv ); + int retval = DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); if( retval == -1 ) throw SocketException( SocketException::cBadRead, "Bad Read error" ); +#ifdef WIN32 + if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &wfds ) ) +#else if( !FD_ISSET( nSocket, &wfds ) ) +#endif return false; return true; } @@ -403,7 +421,7 @@ void Bu::Socket::setBlocking( bool bBlocking ) // socket based on the numerical value of iMode. // If iMode = 0, blocking is enabled; // If iMode != 0, non-blocking mode is enabled. - ioctlsocket(nSocket, FIONBIO, &iMode); + DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); #endif } @@ -416,20 +434,20 @@ bool Bu::Socket::isOpen() return bActive; } -//#ifdef WIN32 -// typedef int socklen_t; -//#endif - void Bu::Socket::setAddress() { struct sockaddr_in addr; socklen_t len = sizeof(addr); addr.sin_family = AF_INET; // getsockname( nSocket, (sockaddr *)(&addr), &len ); - getpeername( nSocket, (sockaddr *)(&addr), &len ); + DYNLOAD getpeername( nSocket, (sockaddr *)(&addr), &len ); +#ifdef WIN32 + DYNLOAD inet_ntoa( sAddress, addr.sin_addr ); +#else char buf[150]; sprintf( buf, "%s", inet_ntoa( addr.sin_addr ) ); sAddress = buf; +#endif } Bu::FString Bu::Socket::getAddress() const diff --git a/src/win32_compatibility.cpp b/src/win32_compatibility.cpp new file mode 100644 index 0000000..372dd6c --- /dev/null +++ b/src/win32_compatibility.cpp @@ -0,0 +1,266 @@ +#include "win32_compatibility.h" + +#ifdef WIN32 + +typedef char * (__cdecl *FNDEF_DYN_inet_ntoa)( struct in_addr ); +void DynamicWinsock2::inet_ntoa( Bu::FString &out, struct in_addr addr_in ) +{ + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_inet_ntoa fn = (FNDEF_DYN_inet_ntoa) + GetProcAddress( Ws2_32, "inet_ntoa" ); + if( fn != NULL ) + out = (fn)( addr_in ); + + //We will let windows clean up our dll imports on exit + //FreeLibrary( Ws2_32 ); + } +} + +typedef unsigned long (__cdecl *FNDEF_DYN_inet_addr)( const char * ); +unsigned long DynamicWinsock2::inet_addr( const char *s_in ) +{ + unsigned long out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_inet_addr fn = (FNDEF_DYN_inet_addr) + GetProcAddress( Ws2_32, "inet_addr" ); + if( fn != NULL ) + out = (fn)( s_in ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_select)( + int nfds,fd_set*,fd_set*,fd_set*,const struct timeval*); +int DynamicWinsock2::select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timeval *timeout) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_select fn = (FNDEF_DYN_select) + GetProcAddress( Ws2_32, "select" ); + if( fn != NULL ) + out = (fn)( nfds, readfds, writefds, exceptfds, timeout ); + } + return out; +} + +typedef SOCKET (__cdecl *FNDEF_DYN_socket)(int,int,int); +SOCKET DynamicWinsock2::socket(int domain, int type, int protocol) +{ + SOCKET out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_socket fn = (FNDEF_DYN_socket) + GetProcAddress( Ws2_32, "socket" ); + if( fn != NULL ) + out = (fn)( domain, type, protocol ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_ioctlsocket)(SOCKET,long,u_long *); +int DynamicWinsock2::ioctlsocket(SOCKET s, long cmd, u_long *argp) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_ioctlsocket fn = (FNDEF_DYN_ioctlsocket) + GetProcAddress( Ws2_32, "ioctlsocket" ); + if( fn != NULL ) + out = (fn)( s, cmd, argp ); + } + return out; +} + +typedef u_short (__cdecl *FNDEF_DYN_htons)(u_short); +u_short DynamicWinsock2::htons(u_short in) +{ + u_short out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_htons fn = (FNDEF_DYN_htons) + GetProcAddress( Ws2_32, "htons" ); + if( fn != NULL ) + out = (fn)( in ); + } + return out; +} + +typedef u_long (__cdecl *FNDEF_DYN_htonl)(u_long); +u_long DynamicWinsock2::htonl(u_long in) +{ + u_long out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_htonl fn = (FNDEF_DYN_htonl) + GetProcAddress( Ws2_32, "htonl" ); + if( fn != NULL ) + out = (fn)( in ); + } + return out; +} + +typedef struct hostent * (__cdecl *FNDEF_DYN_gethostbyname)(const char *); +struct hostent *DynamicWinsock2::gethostbyname(const char *name) +{ + hostent *out = NULL; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_gethostbyname fn = (FNDEF_DYN_gethostbyname) + GetProcAddress( Ws2_32, "gethostbyname" ); + if( fn != NULL ) + out = (fn)( name ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_connect)(SOCKET,const struct sockaddr*,int); +int DynamicWinsock2::connect( + SOCKET s, const struct sockaddr *serv_addr, int addrlen) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_connect fn = (FNDEF_DYN_connect) + GetProcAddress( Ws2_32, "connect" ); + if( fn != NULL ) + out = (fn)( s, serv_addr, addrlen ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_getpeername)(SOCKET,struct sockaddr*,int*); +int DynamicWinsock2::getpeername(SOCKET s, struct sockaddr *name, int *namelen) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_getpeername fn = (FNDEF_DYN_getpeername) + GetProcAddress( Ws2_32, "getpeername" ); + if( fn != NULL ) + out = (fn)( s, name, namelen ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_setsockopt)(SOCKET,int,int,const char*,int); +int DynamicWinsock2::setsockopt(SOCKET s, int level, int optname, + const char *optval, int optlen) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_setsockopt fn = (FNDEF_DYN_setsockopt) + GetProcAddress( Ws2_32, "setsockopt" ); + if( fn != NULL ) + out = (fn)( s, level, optname, optval, optlen ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_bind)(SOCKET,const struct sockaddr*,int); +int DynamicWinsock2::bind(SOCKET s, const struct sockaddr *my_addr, int addrlen) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_bind fn = (FNDEF_DYN_bind) + GetProcAddress( Ws2_32, "bind" ); + if( fn != NULL ) + out = (fn)( s, my_addr, addrlen ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_listen)(SOCKET,int); +int DynamicWinsock2::listen(SOCKET s, int backlog) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_listen fn = (FNDEF_DYN_listen) + GetProcAddress( Ws2_32, "listen" ); + if( fn != NULL ) + out = (fn)( s, backlog ); + } + return out; +} + +typedef SOCKET (__cdecl *FNDEF_DYN_accept)(SOCKET,struct sockaddr*,int*); +SOCKET DynamicWinsock2::accept(SOCKET s, struct sockaddr *addr, int *addrlen) +{ + SOCKET out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_accept fn = (FNDEF_DYN_accept) + GetProcAddress( Ws2_32, "accept" ); + if( fn != NULL ) + out = (fn)( s, addr, addrlen ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_recv)(SOCKET,char*,int,int); +int DynamicWinsock2::recv( SOCKET s, char *buf, int len, int flags ) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_recv fn = (FNDEF_DYN_recv) + GetProcAddress( Ws2_32, "recv" ); + if( fn != NULL ) + out = (fn)( s, buf, len, flags ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN_send)(SOCKET,const char*,int,int); +int DynamicWinsock2::send( SOCKET s, const char *buf, int len, int flags ) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN_send fn = (FNDEF_DYN_send) + GetProcAddress( Ws2_32, "send" ); + if( fn != NULL ) + out = (fn)( s, buf, len, flags ); + } + return out; +} + +typedef int (__cdecl *FNDEF_DYN__WSAFDIsSet)(SOCKET,fd_set*); +int DynamicWinsock2::DYN_FD_ISSET(SOCKET s, fd_set *set) +{ + int out = 0; + HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); + if( Ws2_32 != NULL ) + { + FNDEF_DYN__WSAFDIsSet fn = (FNDEF_DYN__WSAFDIsSet) + GetProcAddress( Ws2_32, "__WSAFDIsSet" ); + if( fn != NULL ) + out = (fn)( s, set ); + } + return out; +} + +#endif + diff --git a/src/win32_compatibility.h b/src/win32_compatibility.h index a1b9c97..7d1f79b 100644 --- a/src/win32_compatibility.h +++ b/src/win32_compatibility.h @@ -8,8 +8,17 @@ #ifndef WIN32_COMPATIBILITY__H #define WIN32_COMPATIBILITY__H +#ifdef WIN32 + #define DYNLOAD DynamicWinsock2:: +#else + #define DYNLOAD +#endif + #ifdef WIN32 +#include +#include "fstring.h" + #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(expression) \ (__extension__ \ @@ -19,9 +28,31 @@ __result; })) #endif -//__extension__ typedef unsigned int socklen_t; __extension__ typedef int socklen_t; +namespace DynamicWinsock2 +{ + void inet_ntoa( Bu::FString &out, struct in_addr addr_in ); + unsigned long inet_addr( const char *s_in ); + int select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timeval *timeout); + SOCKET socket(int domain, int type, int protocol); + int ioctlsocket(SOCKET s, long cmd, u_long *argp); + u_short htons(u_short in); + u_long htonl(u_long in); + struct hostent *gethostbyname(const char *name); + int connect(SOCKET s, const struct sockaddr *serv_addr, int addrlen); + int getpeername(SOCKET s, struct sockaddr *name, int *namelen); + int setsockopt(SOCKET s, int level, int optname, + const char *optval, int optlen); + int bind(SOCKET s, const struct sockaddr *my_addr, int addrlen); + int listen(SOCKET s, int backlog); + SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen); + int recv( SOCKET s, char *buf, int len, int flags ); + int send( SOCKET s, const char *buf, int len, int flags ); + int DYN_FD_ISSET(SOCKET s, fd_set *set); +}; + #endif /* WIN32 */ #endif -- cgit v1.2.3