From 8c1f4d7bace6ff2c99d546cedaba890b349e88f8 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 16 Jan 2009 23:55:53 +0000 Subject: I...think that's a little better. Wow, function pointers in windows have a lot of problems. This may require a little more research, but basically, you can't just call them inline wherever you'd like. I managed to get it to work by providing simple one line wrapper functions for each function we acquired as a pointer. Crazy mess. Anyway, it should load the library just once now, and Bu::Socket looks a little bit cleaner, but not a heck of a lot. I also added some more docs and removed the author references. --- src/bitstring.h | 1 - src/client.h | 1 - src/ito.h | 1 - src/itoatom.h | 1 - src/itocondition.h | 1 - src/itocounter.h | 1 - src/itomutex.h | 1 - src/itoqueue.h | 1 - src/itoserver.h | 1 - src/linkmessage.h | 1 - src/linux_compatibility.h | 21 +++ src/programchain.h | 6 - src/programlink.h | 1 - src/protocol.h | 1 - src/server.h | 1 - src/serversocket.cpp | 29 ++- src/serversocket.h | 1 - src/singleton.h | 1 - src/socket.cpp | 146 ++++----------- src/socket.h | 27 ++- src/win32_compatibility.cpp | 434 ++++++++++++-------------------------------- src/win32_compatibility.h | 110 +++++++---- 22 files changed, 283 insertions(+), 505 deletions(-) create mode 100644 src/linux_compatibility.h diff --git a/src/bitstring.h b/src/bitstring.h index f124d2d..9f0c719 100644 --- a/src/bitstring.h +++ b/src/bitstring.h @@ -14,7 +14,6 @@ namespace Bu * * For more general and mathematical type interaction see BitStringInt. * - *@author Mike Buland */ class BitString { diff --git a/src/client.h b/src/client.h index ae2815b..b11774e 100644 --- a/src/client.h +++ b/src/client.h @@ -19,7 +19,6 @@ namespace Bu class ClientLinkFactory; /** - *@author Mike Buland *@ingroup Serving */ class Client diff --git a/src/ito.h b/src/ito.h index 009d4b1..9829d28 100644 --- a/src/ito.h +++ b/src/ito.h @@ -17,7 +17,6 @@ namespace Bu * system in an object oriented sort of way. It allows you to create a * class with standard member variables and callable functions that can be * run in it's own thread, one per class instance. - *@author Mike Buland *@ingroup Threading */ class Ito diff --git a/src/itoatom.h b/src/itoatom.h index 4eaa13c..2791519 100644 --- a/src/itoatom.h +++ b/src/itoatom.h @@ -15,7 +15,6 @@ /** * A thread-safe wrapper class. - *@author Mike Buland *@ingroup Threading */ template diff --git a/src/itocondition.h b/src/itocondition.h index 7300920..8cae427 100644 --- a/src/itocondition.h +++ b/src/itocondition.h @@ -34,7 +34,6 @@ namespace Bu * The usage for the triggering thread is much simpler, when it needs to * tell the others that it's time to grab some data it calls either signal * or broadcast. See both of those functions for the difference. - *@author Mike Buland *@ingroup Threading */ class ItoCondition : public ItoMutex diff --git a/src/itocounter.h b/src/itocounter.h index 58abe07..afca8da 100644 --- a/src/itocounter.h +++ b/src/itocounter.h @@ -15,7 +15,6 @@ namespace Bu /** * A simple thread-safe counter class. This is handy for assigning unique * IDs to objects that are being created in different threads. - *@author Mike Buland *@ingroup Threading Containers */ template diff --git a/src/itomutex.h b/src/itomutex.h index 0521b81..80930cc 100644 --- a/src/itomutex.h +++ b/src/itomutex.h @@ -17,7 +17,6 @@ namespace Bu * except keep all of the functionality together in an OO sorta' way and * keep you from having to worry about cleaning up your mutexes properly, * or initing them. - *@author Mike Buland *@ingroup Threading */ class ItoMutex diff --git a/src/itoqueue.h b/src/itoqueue.h index a481f87..3a116e2 100644 --- a/src/itoqueue.h +++ b/src/itoqueue.h @@ -22,7 +22,6 @@ namespace Bu * infinite blocking, or with timed blocking, which will return a value if * something is enqueued within the specified time limit, or NULL if the * time limit is exceded. - *@author Mike Buland *@ingroup Threading Containers */ template diff --git a/src/itoserver.h b/src/itoserver.h index 0256f87..bcdd1d1 100644 --- a/src/itoserver.h +++ b/src/itoserver.h @@ -45,7 +45,6 @@ namespace Bu * In order to use a Server you must subclass it and implement the pure * virtual functions. These allow you to receive notification of events * happening within the server itself, and actually makes it useful. - *@author Mike Buland *@ingroup Threading Serving */ class ItoServer : public Ito diff --git a/src/linkmessage.h b/src/linkmessage.h index c9abd04..5b8b7e2 100644 --- a/src/linkmessage.h +++ b/src/linkmessage.h @@ -17,7 +17,6 @@ namespace Bu * A message to be broadcast accross ProgramLinks in a ProgramChain. Generally * one would make a subclass of this in order to transmit more useful * information, but sometimes it isn't necesarry. - *@author Mike Buland */ class LinkMessage { diff --git a/src/linux_compatibility.h b/src/linux_compatibility.h new file mode 100644 index 0000000..67016a7 --- /dev/null +++ b/src/linux_compatibility.h @@ -0,0 +1,21 @@ +#ifdef __linux__ + +#define bu_inet_ntoa inet_ntoa +#define bu_inet_addr inet_addr +#define bu_select select +#define bu_socket socket +#define bu_htons htons +#define bu_htonl htonl +#define bu_gethostbyname gethostbyname +#define bu_freeaddrinfo freeaddrinfo +#define bu_getaddrinfo getaddrinfo +#define bu_connect connect +#define bu_getpeername getpeername +#define bu_setsockopt setsockopt +#define bu_bind bind +#define bu_listen listen +#define bu_accept accept + +#define bu_gai_strerror gai_strerror + +#endif diff --git a/src/programchain.h b/src/programchain.h index bd4f658..c50e1c2 100644 --- a/src/programchain.h +++ b/src/programchain.h @@ -17,7 +17,6 @@ namespace Bu /** * The Program Chain links together program "chunks" to more easily facilitate * a generalized program loop with modular extensions. - *@author Mike Buland */ class ProgramChain { @@ -36,7 +35,6 @@ namespace Bu * Adds a link to the end of the chain. *@param pLink A pointer to the link to add to the chain. *@returns True if adding the link was successful, otherwise false - *@author Mike Buland */ bool addLink( Bu::ProgramLink *pLink ); @@ -46,14 +44,12 @@ namespace Bu * name, apparently. *@returns A pointer to the specified ProgramLink, or NULL if none were * found matching your criteria. - *@author Mike Buland */ class ProgramLink *getLink( const char *lpName ); /** * Gets the very first link in the chain. *@returns A pointer to the first link in the chain. - *@author Mike Buland */ class ProgramLink *getBaseLink(); @@ -62,7 +58,6 @@ namespace Bu * over the operation of the chain. *@returns true if every link returned true. If at least one link returns * false, then returns false. - *@author Mike Buland */ bool execChainOnce(); @@ -72,7 +67,6 @@ namespace Bu * a link returns a false value. *@returns False, always. It returns true unless a link returned false, * but loops until a link does return false. - *@author Mike Buland **/ bool enterChainLoop(); diff --git a/src/programlink.h b/src/programlink.h index dfbbdb5..d34a3df 100644 --- a/src/programlink.h +++ b/src/programlink.h @@ -16,7 +16,6 @@ namespace Bu /** * Program Link is the base class for any object that will be a piece of the * main program chain loop. - *@author Mike Buland */ class ProgramLink { diff --git a/src/protocol.h b/src/protocol.h index 64e5ca7..6009fe5 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,6 @@ namespace Bu class Client; /** - *@author Mike Buland *@ingroup Serving */ class Protocol diff --git a/src/server.h b/src/server.h index 55de081..315248b 100644 --- a/src/server.h +++ b/src/server.h @@ -41,7 +41,6 @@ namespace Bu * In order to use a Server you must subclass it and implement the pure * virtual functions. These allow you to receive notification of events * happening within the server itself, and actually makes it useful. - *@author Mike Buland *@ingroup Serving */ class Server diff --git a/src/serversocket.cpp b/src/serversocket.cpp index 946d0d3..89fef7e 100644 --- a/src/serversocket.cpp +++ b/src/serversocket.cpp @@ -24,6 +24,7 @@ #include "bu/serversocket.h" #include "bu/osx_compatibility.h" #include "bu/win32_compatibility.h" +#include "bu/linux_compatibility.h" namespace Bu { subExceptionDef( ServerSocketException ) } @@ -35,11 +36,11 @@ Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) : /* Give the socket a name. */ name.sin_family = AF_INET; - name.sin_port = DYNLOAD htons( nPort ); + name.sin_port = bu_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 = DYNLOAD htonl( INADDR_ANY ); + name.sin_addr.s_addr = bu_htonl( INADDR_ANY ); startServer( name, nPoolSize ); } @@ -53,10 +54,10 @@ Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) : /* Give the socket a name. */ name.sin_family = AF_INET; - name.sin_port = DYNLOAD htons( nPort ); + name.sin_port = bu_htons( nPort ); #ifdef WIN32 - name.sin_addr.s_addr = DYNLOAD inet_addr( sAddr.getStr() ); + name.sin_addr.s_addr = bu_inet_addr( sAddr.getStr() ); #else inet_aton( sAddr.getStr(), &name.sin_addr ); #endif @@ -72,7 +73,7 @@ Bu::ServerSocket::~ServerSocket() void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) { /* Create the socket. */ - nServer = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); + nServer = bu_socket( PF_INET, SOCK_STREAM, 0 ); if( nServer < 0 ) { @@ -80,7 +81,7 @@ void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) } int opt = 1; - DYNLOAD setsockopt( + bu_setsockopt( nServer, SOL_SOCKET, SO_REUSEADDR, @@ -88,13 +89,12 @@ void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) sizeof( opt ) ); - if( DYNLOAD bind( - nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) + if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) { throw Bu::ServerSocketException("Couldn't bind to the listen socket."); } - if( DYNLOAD listen( nServer, nPoolSize ) < 0 ) + if( bu_listen( nServer, nPoolSize ) < 0 ) { throw Bu::ServerSocketException( "Couldn't begin listening to the server socket." @@ -121,18 +121,14 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) xT.tv_usec = nTimeoutUSec; if( TEMP_FAILURE_RETRY( - DYNLOAD select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) + bu_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; @@ -140,8 +136,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) size = sizeof( clientname ); #ifdef WIN32 - nClient = DYNLOAD accept( - nServer, (struct sockaddr *)&clientname, (int *)&size); + nClient = bu_accept( nServer, (struct sockaddr *)&clientname, &size); #else /* not-WIN32 */ #ifdef __CYGWIN__ nClient = ::accept( nServer, (struct sockaddr *)&clientname, @@ -189,7 +184,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; - DYNLOAD ioctlsocket(nClient, FIONBIO, &iMode); + bu_ioctlsocket(nClient, FIONBIO, &iMode); #endif } diff --git a/src/serversocket.h b/src/serversocket.h index 168c5e1..0860972 100644 --- a/src/serversocket.h +++ b/src/serversocket.h @@ -32,7 +32,6 @@ namespace Bu * Although the accept function returns an integral file descriptor, it is * designed to be used with the Socket class. * - *@author Mike Buland *@ingroup Serving */ class ServerSocket diff --git a/src/singleton.h b/src/singleton.h index 7bdf97f..0bcc3f7 100644 --- a/src/singleton.h +++ b/src/singleton.h @@ -33,7 +33,6 @@ namespace Bu * You can still add public functions and variables to your new Singleton child * class, but your constructor should be protected (hence the need for the * friend decleration). - *@author Mike Buland */ template class Singleton diff --git a/src/socket.cpp b/src/socket.cpp index c57d97e..dd19d39 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -14,9 +14,10 @@ #include #include #include -#include "socket.h" -#include "osx_compatibility.h" -#include "win32_compatibility.h" +#include "bu/socket.h" +#include "bu/osx_compatibility.h" +#include "bu/win32_compatibility.h" +#include "bu/linux_compatibility.h" #ifndef WIN32 #include @@ -36,7 +37,7 @@ Bu::Socket::Socket( int nSocket ) : bActive( true ) { #ifdef WIN32 - DynamicWinsock2::Winsock2::getInstance(); + Bu::Winsock2::getInstance(); #endif setAddress(); } @@ -44,37 +45,19 @@ Bu::Socket::Socket( int nSocket ) : Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) { #ifdef WIN32 - DynamicWinsock2::Winsock2::getInstance(); + Bu::Winsock2::getInstance(); #endif bActive = false; /* Create the socket. */ - nSocket = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); + nSocket = bu_socket( PF_INET, SOCK_STREAM, 0 ); if( nSocket < 0 ) { throw ExceptionBase("Couldn't create socket.\n"); } - // These lines set the socket to non-blocking, a good thing? -#ifndef WIN32 - int flags; - flags = fcntl(nSocket, F_GETFL, 0); - flags |= O_NONBLOCK; - if (fcntl(nSocket, F_SETFL, flags) < 0) - { - throw Bu::SocketException("Couldn't set socket options.\n"); - } -#else - //------------------------- - // Set the socket I/O mode: In this case FIONBIO - // enables or disables the blocking mode for the - // socket based on the numerical value of iMode. - // If iMode = 0, blocking is enabled; - // If iMode != 0, non-blocking mode is enabled. - u_long iMode = 1; - DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); -#endif + setBlocking( false ); /* Connect to the server. */ //printf("Resolving hostname (%s)...\n", sAddr ); @@ -89,19 +72,14 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) sprintf( ibuf, "%d", nPort ); int ret; - if( (ret = DYNLOAD getaddrinfo( + if( (ret = bu_getaddrinfo( sAddr.getStr(), ibuf, &aiHints, &pAddr )) != 0 ) { - #ifdef WIN32 - throw Bu::SocketException("Couldn't resolve hostname %s (%d).\n", - sAddr.getStr(), DYNLOAD WSAGetLastError()); - #else throw Bu::SocketException("Couldn't resolve hostname %s (%s).\n", - sAddr.getStr(), DYNLOAD gai_strerror(ret)); - #endif + sAddr.getStr(), bu_gai_strerror(ret)); } - DYNLOAD connect( + bu_connect( nSocket, pAddr->ai_addr, pAddr->ai_addrlen @@ -109,7 +87,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) sAddress = pAddr->ai_canonname; - DYNLOAD freeaddrinfo( pAddr ); + bu_freeaddrinfo( pAddr ); } bActive = true; @@ -130,7 +108,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) tv.tv_sec = nTimeout; tv.tv_usec = 0; - retval = DYNLOAD select( nSocket+1, &rfds, &wfds, &efds, &tv ); + retval = bu_select( nSocket+1, &rfds, &wfds, &efds, &tv ); if( retval == 0 ) { @@ -156,75 +134,20 @@ void Bu::Socket::close() bActive = false; } -/* -void Bu::Socket::read() -{ - char buffer[RBS]; - int nbytes; - int nTotalRead=0; - - for(;;) - { - //memset( buffer, 0, RBS ); - - nbytes = ::read( nSocket, buffer, RBS ); - if( nbytes < 0 && errno != 0 && errno != EAGAIN ) - { - //printf("errno: %d, %s\n", errno, strerror( errno ) ); - //perror("readInput"); - throw SocketException( - SocketException::cRead, - "Read error: %s", - strerror( errno ) - ); - } - else - { - if( nbytes <= 0 ) - break; - nTotalRead += nbytes; - sReadBuf.append( buffer, nbytes ); - if( nbytes < RBS ) - { - break; - } - - // New test, if data is divisible by RBS bytes on some libs the - // read could block, this keeps it from happening. - { - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(nSocket, &rfds); - struct timeval tv = { 0, 0 }; - int retval = select( nSocket+1, &rfds, NULL, NULL, &tv ); - if( retval == -1 ) - throw SocketException( - SocketException::cBadRead, - "Bad Read error" - ); - if( !FD_ISSET( nSocket, &rfds ) ) - break; - } - } - } -}*/ - size_t Bu::Socket::read( void *pBuf, size_t nBytes ) { #ifdef WIN32 int nRead = TEMP_FAILURE_RETRY( - DYNLOAD recv( nSocket, (char *) pBuf, nBytes, 0 ) ); + bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); #else int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); #endif if( nRead < 0 ) { #ifdef WIN32 - int iWSAError = DYNLOAD WSAGetLastError(); + int iWSAError = bu_WSAGetLastError(); if( iWSAError == WSAEWOULDBLOCK ) return 0; - printf( "WSAGetLastError: %d\n", iWSAError ); - return 0; #else if( errno == EAGAIN ) return 0; @@ -259,7 +182,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, { tv.tv_sec = nSec; tv.tv_usec = nUSec; - DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); + bu_select( nSocket+1, &rfds, NULL, NULL, &tv ); nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); if( nRead >= nBytes ) break; @@ -282,13 +205,19 @@ 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 ) ); + bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); #else int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); #endif if( nWrote < 0 ) { +#ifdef WIN32 + int iWSAError = bu_WSAGetLastError(); + if( iWSAError == WSAEWOULDBLOCK ) + return 0; +#else if( errno == EAGAIN ) return 0; +#endif throw SocketException( SocketException::cWrite, strerror(errno) ); } return nWrote; @@ -318,7 +247,7 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32 { tv.tv_sec = nSec; tv.tv_usec = nUSec; - DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); + bu_select( nSocket+1, NULL, &wfds, NULL, &tv ); nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); if( nWrote >= nBytes ) break; @@ -368,17 +297,14 @@ bool Bu::Socket::canRead() FD_ZERO(&rfds); FD_SET(nSocket, &rfds); struct timeval tv = { 0, 0 }; - int retval = DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); + int retval = bu_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; } @@ -389,17 +315,13 @@ bool Bu::Socket::canWrite() FD_ZERO(&wfds); FD_SET(nSocket, &wfds); struct timeval tv = { 0, 0 }; - int retval = DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); + int retval = bu_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; } @@ -447,7 +369,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. - DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); + bu_ioctlsocket(nSocket, FIONBIO, &iMode); #endif } @@ -465,15 +387,8 @@ void Bu::Socket::setAddress() struct sockaddr_in addr; socklen_t len = sizeof(addr); addr.sin_family = AF_INET; - // getsockname( 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_getpeername( nSocket, (sockaddr *)(&addr), &len ); + sAddress = bu_inet_ntoa( addr.sin_addr ); } Bu::FString Bu::Socket::getAddress() const @@ -485,3 +400,4 @@ Bu::Socket::operator int() const { return nSocket; } + diff --git a/src/socket.h b/src/socket.h index 572c2ad..f12f79c 100644 --- a/src/socket.h +++ b/src/socket.h @@ -27,7 +27,32 @@ namespace Bu subExceptionDeclEnd(); /** - *@author Mike Buland + * Network socket stream class. This class provides a mechanism for + * communicating over a network using TCP/IP. It will provide other low + * level protocol and addressing support later on, but for now it's just + * standard STREAM TCP/IP sockets. + * + * Unlike system sockets, these sockets are opened by default in + * non-blocking mode, you can specify your own timeout for opening a socket, + * and a number of non-fatal error messages have been automatically handled + * and treated as standard no-data-available-yet situations on read. + * + * Please note that there is a condition that will occur eventually (at + * least on *nix systems) that will trigger a SIGPIPE condition. This + * will terminate your program immediately unless handled properly. Most + * people doing any connections with Socket will want to put this in their + * program somewhere before they use it: + *@code + #include + ... + ... + ... + sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::Socket + @endcode + * When this is done, Bu::Socket will simply throw a broken pipe exception + * just like every other error condition, allowing your program to handle + * it sanely. + * *@ingroup Serving *@ingroup Streams */ diff --git a/src/win32_compatibility.cpp b/src/win32_compatibility.cpp index 54fd56c..b85e869 100644 --- a/src/win32_compatibility.cpp +++ b/src/win32_compatibility.cpp @@ -2,352 +2,152 @@ #ifdef WIN32 -typedef int (__cdecl *FNDEF_DYN_WSAStartup)(WORD,LPWSADATA); -int DynamicWinsock2::WSAStartup( - WORD wVersionRequested,LPWSADATA lpWSAData) +#define deffunc( name ) \ + Bu::Winsock2::FNDEF_DYN_ ##name Bu::Winsock2::_fnptr_ ##name = NULL + +char Bu::Winsock2::scode[15]; + +deffunc( WSAStartup ); +deffunc( WSACleanup ); +deffunc( WSAGetLastError ); +deffunc( inet_ntoa ); +deffunc( inet_addr ); +deffunc( select ); +deffunc( socket ); +deffunc( ioctlsocket ); +deffunc( htons ); +deffunc( htonl ); +deffunc( gethostbyname ); +deffunc( freeaddrinfo ); +deffunc( getaddrinfo ); +deffunc( connect ); +deffunc( getpeername ); +deffunc( setsockopt ); +deffunc( bind ); +deffunc( listen ); +deffunc( accept ); +deffunc( recv ); +deffunc( send ); +deffunc( __WSAFDIsSet ); + +// Safely get a function from the library +#define getfunc( name ) \ + Bu::Winsock2::_fnptr_ ##name = (FNDEF_DYN_ ##name) \ + GetProcAddress( Ws2_32, #name ); \ + if( Bu::Winsock2::_fnptr_ ##name == NULL ) { \ + throw Bu::ExceptionBase("Error loading function " #name " from dll.");\ + } (void)0 + +Bu::Winsock2::Winsock2() { - int out=0; - HINSTANCE Ws2_32 = LoadLibrary(TEXT("WS2_32.DLL")); - if( Ws2_32 != NULL ) - { - FNDEF_DYN_WSAStartup fn = (FNDEF_DYN_WSAStartup) - GetProcAddress( Ws2_32, "WSAStartup" ); - if( fn != NULL ) - out = (fn)(wVersionRequested,lpWSAData); - } - return out; -} + Ws2_32 = LoadLibrary(TEXT("WS2_32.DLL")); + + getfunc( WSAStartup ); + getfunc( WSACleanup ); + getfunc( WSAGetLastError ); + getfunc( inet_ntoa ); + getfunc( inet_addr ); + getfunc( select ); + getfunc( socket ); + getfunc( ioctlsocket ); + getfunc( htons ); + getfunc( htonl ); + getfunc( gethostbyname ); + getfunc( freeaddrinfo ); + getfunc( getaddrinfo ); + getfunc( connect ); + getfunc( getpeername ); + getfunc( setsockopt ); + getfunc( bind ); + getfunc( listen ); + getfunc( accept ); + getfunc( recv ); + getfunc( send ); + getfunc( __WSAFDIsSet ); -typedef int (__cdecl *FNDEF_DYN_WSACleanup)(); -int DynamicWinsock2::WSACleanup() -{ - int out=0; - HINSTANCE Ws2_32 = LoadLibrary(TEXT("WS2_32.DLL")); - if( Ws2_32 != NULL ) - { - FNDEF_DYN_WSACleanup fn = (FNDEF_DYN_WSACleanup) - GetProcAddress( Ws2_32, "WSACleanup" ); - if( fn != NULL ) - out = (fn)(); - } - return out; + Bu::Winsock2::WSAStartup( MAKEWORD(2, 2), &wsaData ); } -//typedef char * (__cdecl *FNDEF_DYN_gai_strerrorA)( int ecode ); -typedef int (__cdecl *FNDEF_DYN_WSAGetLastError)(void); -int DynamicWinsock2::WSAGetLastError() +Bu::Winsock2::~Winsock2() { - int out=0; - HINSTANCE Ws2_32 = LoadLibrary(TEXT("WS2_32.DLL")); - if( Ws2_32 != NULL ) - { - FNDEF_DYN_WSAGetLastError fn = (FNDEF_DYN_WSAGetLastError) - GetProcAddress( Ws2_32, "WSAGetLastError" ); - if( fn != NULL ) - out = (fn)(); - } - return out; + Bu::Winsock2::WSACleanup(); + FreeLibrary( Ws2_32 ); } -typedef char * (__cdecl *FNDEF_DYN_inet_ntoa)( struct in_addr ); -void DynamicWinsock2::inet_ntoa( Bu::FString &out, struct in_addr addr_in ) +char *Bu::Winsock2::gai_strerror( int iCode ) { - 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 ); - } + sprintf( scode, "%d", Bu::Winsock2::WSAGetLastError() ); + return scode; } -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; +int Bu::Winsock2::WSAStartup( WORD a, LPWSADATA b ) { + return (*Bu::Winsock2::_fnptr_WSAStartup)( a, b ); } - -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; +int Bu::Winsock2::WSACleanup( ) { + return (*Bu::Winsock2::_fnptr_WSACleanup)(); } - -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; +int Bu::Winsock2::WSAGetLastError( ) { + return (*Bu::Winsock2::_fnptr_WSAGetLastError)(); } - -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; +char * Bu::Winsock2::inet_ntoa( struct in_addr a ) { + return (*Bu::Winsock2::_fnptr_inet_ntoa)( a ); } - -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; +unsigned long Bu::Winsock2::inet_addr( const char *s_in ) { + return (*Bu::Winsock2::_fnptr_inet_addr)( s_in ); } - -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; +int Bu::Winsock2::select( int a, fd_set *b, fd_set *c, fd_set *d, + const struct timeval *e ) { + return (*Bu::Winsock2::_fnptr_select)( a, b, c, d, e ); } - -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; +SOCKET Bu::Winsock2::socket( int domain, int type, int protocol ) { + return (*Bu::Winsock2::_fnptr_socket)( domain, type, protocol ); } - -typedef void (__cdecl *FNDEF_DYN_freeaddrinfo)(struct addrinfo *); -void DynamicWinsock2::freeaddrinfo(struct addrinfo *ai) -{ - HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); - if( Ws2_32 != NULL ) - { - FNDEF_DYN_freeaddrinfo fn = (FNDEF_DYN_freeaddrinfo) - GetProcAddress( Ws2_32, "freeaddrinfo" ); - if( fn != NULL ) - (fn)( ai ); - } +int Bu::Winsock2::ioctlsocket( SOCKET s, long cmd, u_long *argp ) { + return (*Bu::Winsock2::_fnptr_ioctlsocket)( s, cmd, argp ); } - -typedef int (__cdecl *FNDEF_DYN_getaddrinfo)( - const char*,const char*,const struct addrinfo*,struct addrinfo**); -int DynamicWinsock2::getaddrinfo( - const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res ) -{ - int out = 0; - HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); - if( Ws2_32 != NULL ) - { - FNDEF_DYN_getaddrinfo fn = (FNDEF_DYN_getaddrinfo) - GetProcAddress( Ws2_32, "getaddrinfo" ); - if( fn != NULL ) - out = (fn)( nodename, servname, hints, res ); - } - return out; +u_short Bu::Winsock2::htons( u_short in ) { + return (*Bu::Winsock2::_fnptr_htons)( in ); +} +u_long Bu::Winsock2::htonl( u_long in ) { + return (*Bu::Winsock2::_fnptr_htonl)( in ); } - -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; +struct hostent * Bu::Winsock2::gethostbyname( const char *name ) { + return (*Bu::Winsock2::_fnptr_gethostbyname)( name ); } - -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; +void Bu::Winsock2::freeaddrinfo( struct addrinfo *ai ) { + return (*Bu::Winsock2::_fnptr_freeaddrinfo)( ai ); } - -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; +int Bu::Winsock2::getaddrinfo( const char *a, const char *b, + const struct addrinfo *c, struct addrinfo **d ) { + return (*Bu::Winsock2::_fnptr_getaddrinfo)( a, b, c, d ); } - -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; +int Bu::Winsock2::connect( SOCKET s, const struct sockaddr *a, int b ) { + return (*Bu::Winsock2::_fnptr_connect)( s, a, b ); } - -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; +int Bu::Winsock2::getpeername( SOCKET s, struct sockaddr *a, int *b ) { + return (*Bu::Winsock2::_fnptr_getpeername)( s, a, b); } - -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; +int Bu::Winsock2::setsockopt( SOCKET s, int a, int b, + const char *c, int d ) { + return (*Bu::Winsock2::_fnptr_setsockopt)( s, a, b, c, d ); } - -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; +int Bu::Winsock2::bind( SOCKET s, const struct sockaddr *a, int b ) { + return (*Bu::Winsock2::_fnptr_bind)( s, a, b ); } - -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; +int Bu::Winsock2::listen( SOCKET s, int backlog ) { + return (*Bu::Winsock2::_fnptr_listen)( s, backlog ); } - -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; +SOCKET Bu::Winsock2::accept( SOCKET s, struct sockaddr *a, int *b ) { + return (*Bu::Winsock2::_fnptr_accept)( s, a, b ); } - -DynamicWinsock2::Winsock2::Winsock2() -{ - DynamicWinsock2::WSAStartup( MAKEWORD(2, 2), &wsaData ); +int Bu::Winsock2::recv( SOCKET s, char *buf, int len, int flags ) { + return (*Bu::Winsock2::_fnptr_recv)( s, buf, len, flags ); } - -DynamicWinsock2::Winsock2::~Winsock2() -{ - DynamicWinsock2::WSACleanup(); +int Bu::Winsock2::send( SOCKET s, const char *buf, int len, int flags ) { + return (*Bu::Winsock2::_fnptr_send)( s, buf, len, flags ); +} +int Bu::Winsock2::__WSAFDIsSet( SOCKET s, fd_set *set ) { + return (*Bu::Winsock2::_fnptr___WSAFDIsSet)( s, set ); } #endif diff --git a/src/win32_compatibility.h b/src/win32_compatibility.h index 2d3c52b..36613d1 100644 --- a/src/win32_compatibility.h +++ b/src/win32_compatibility.h @@ -8,12 +8,6 @@ #ifndef WIN32_COMPATIBILITY__H #define WIN32_COMPATIBILITY__H -#ifdef WIN32 - #define DYNLOAD DynamicWinsock2:: -#else - #define DYNLOAD -#endif - #ifdef WIN32 #ifdef __cplusplus @@ -36,37 +30,19 @@ extern "C" __result; })) #endif +#define decltype( ret, name, ... ) \ + typedef ret (__cdecl *FNDEF_DYN_ ##name)( __VA_ARGS__ ); \ + static FNDEF_DYN_ ##name _fnptr_ ##name; \ + static ret name( __VA_ARGS__ ) + __extension__ typedef int socklen_t; -namespace DynamicWinsock2 -{ - int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData); - int WSACleanup(void); - int WSAGetLastError(); - 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); - void freeaddrinfo(struct addrinfo *ai); - int getaddrinfo( - const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res ); - 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); +#ifdef gai_strerror +#undef gai_strerror +#endif +namespace Bu +{ class Winsock2 : public Bu::Singleton { friend class Bu::Singleton; @@ -75,11 +51,77 @@ namespace DynamicWinsock2 virtual ~Winsock2(); WSADATA wsaData; + HINSTANCE Ws2_32; public: + // decltype( return type, function name<, optional parameters> ) + decltype( int, WSAStartup, WORD, LPWSADATA ); + decltype( int, WSACleanup ); + decltype( int, WSAGetLastError ); + decltype( char *, inet_ntoa, struct in_addr ); + decltype( unsigned long, inet_addr, const char *s_in ); + decltype( int, select, int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timeval *timeout ); + decltype( SOCKET, socket, int domain, int type, int protocol ); + decltype( int, ioctlsocket, SOCKET s, long cmd, u_long *argp ); + decltype( u_short, htons, u_short in ); + decltype( u_long, htonl, u_long in ); + decltype( struct hostent *, gethostbyname, const char *name ); + decltype( void, freeaddrinfo, struct addrinfo *ai ); + decltype( int, getaddrinfo, const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res ); + decltype( int, connect, SOCKET s, const struct sockaddr *serv_addr, + int addrlen ); + decltype( int, getpeername, SOCKET s, struct sockaddr *name, + int *namelen ); + decltype( int, setsockopt, SOCKET s, int level, int optname, + const char *optval, int optlen ); + decltype( int, bind, SOCKET s, const struct sockaddr *my_addr, + int addrlen ); + decltype( int, listen, SOCKET s, int backlog ); + decltype( SOCKET, accept, SOCKET s, struct sockaddr *addr, + int *addrlen); + decltype( int, recv, SOCKET s, char *buf, int len, int flags ); + decltype( int, send, SOCKET s, const char *buf, int len, int flags ); + decltype( int, __WSAFDIsSet, SOCKET s, fd_set *set ); + + static char scode[15]; + static char *gai_strerror( int iCode ); }; }; +#ifdef FD_ISSET +#undef FD_ISSET +#endif + +#define bu_WSAStartup (*Bu::Winsock2::WSAStartup) +#define bu_WSACleanup (*Bu::Winsock2::WSACleanup) +#define bu_WSAGetLastError (*Bu::Winsock2::WSAGetLastError) +#define bu_inet_ntoa (*Bu::Winsock2::inet_ntoa) +#define bu_inet_addr (*Bu::Winsock2::inet_addr) +#define bu_select (*Bu::Winsock2::select) +#define bu_socket (*Bu::Winsock2::socket) +#define bu_ioctlsocket (*Bu::Winsock2::ioctlsocket) +#define bu_htons (*Bu::Winsock2::htons) +#define bu_htonl (*Bu::Winsock2::htonl) +#define bu_gethostbyname (*Bu::Winsock2::gethostbyname) +#define bu_freeaddrinfo (*Bu::Winsock2::freeaddrinfo) +#define bu_getaddrinfo (*Bu::Winsock2::getaddrinfo) +#define bu_connect (*Bu::Winsock2::connect) +#define bu_getpeername (*Bu::Winsock2::getpeername) +#define bu_setsockopt (*Bu::Winsock2::setsockopt) +#define bu_bind (*Bu::Winsock2::bind) +#define bu_listen (*Bu::Winsock2::listen) +#define bu_accept (*Bu::Winsock2::accept) +#define bu_recv (*Bu::Winsock2::recv) +#define bu_send (*Bu::Winsock2::send) +#define bu___WSAFDIsSet (*Bu::Winsock2::__WSAFDIsSet) + +#define FD_ISSET (*Bu::Winsock2::__WSAFDIsSet) +#define bu_gai_strerror Bu::Winsock2::gai_strerror + +#undef decltype + #endif /* WIN32 */ #endif -- cgit v1.2.3