diff options
| author | David <david@xagasoft.com> | 2008-10-27 16:07:50 +0000 | 
|---|---|---|
| committer | David <david@xagasoft.com> | 2008-10-27 16:07:50 +0000 | 
| commit | 61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9 (patch) | |
| tree | 530a0d86ca1043dbc04cd7513bc5dd65768a266d | |
| parent | f7e8658f2274044bb452492b1af7e2cd5f82082c (diff) | |
| download | libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.gz libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.bz2 libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.tar.xz libbu++-61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9.zip | |
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...
Diffstat (limited to '')
| -rw-r--r-- | buildMinGW.conf | 2 | ||||
| -rw-r--r-- | src/serversocket.cpp | 47 | ||||
| -rw-r--r-- | src/socket.cpp | 90 | ||||
| -rw-r--r-- | src/win32_compatibility.cpp | 266 | ||||
| -rw-r--r-- | src/win32_compatibility.h | 33 | 
5 files changed, 383 insertions, 55 deletions
| 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"): | |||
| 22 | target file, | 22 | target file, | 
| 23 | set "CXXFLAGS" += "-I.", | 23 | set "CXXFLAGS" += "-I.", | 
| 24 | #input filesIn("src") filter regexp("^.*\\.cpp$") | 24 | #input filesIn("src") filter regexp("^.*\\.cpp$") | 
| 25 | 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"] | 25 | 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"] | 
| 26 | 26 | ||
| 27 | rule "exe": | 27 | rule "exe": | 
| 28 | matches regexp("(.*)\\.win_o$"), | 28 | 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 ) : | |||
| 35 | 35 | ||
| 36 | /* Give the socket a name. */ | 36 | /* Give the socket a name. */ | 
| 37 | name.sin_family = AF_INET; | 37 | name.sin_family = AF_INET; | 
| 38 | name.sin_port = htons( nPort ); | 38 | name.sin_port = DYNLOAD htons( nPort ); | 
| 39 | 39 | ||
| 40 | // I think this specifies who we will accept connections from, | 40 | // I think this specifies who we will accept connections from, | 
| 41 | // a good thing to make configurable later on | 41 | // a good thing to make configurable later on | 
| 42 | name.sin_addr.s_addr = htonl( INADDR_ANY ); | 42 | name.sin_addr.s_addr = DYNLOAD htonl( INADDR_ANY ); | 
| 43 | 43 | ||
| 44 | startServer( name, nPoolSize ); | 44 | startServer( name, nPoolSize ); | 
| 45 | } | 45 | } | 
| @@ -52,10 +52,11 @@ Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) : | |||
| 52 | 52 | ||
| 53 | /* Give the socket a name. */ | 53 | /* Give the socket a name. */ | 
| 54 | name.sin_family = AF_INET; | 54 | name.sin_family = AF_INET; | 
| 55 | name.sin_port = htons( nPort ); | 55 | |
| 56 | name.sin_port = DYNLOAD htons( nPort ); | ||
| 56 | 57 | ||
| 57 | #ifdef WIN32 | 58 | #ifdef WIN32 | 
| 58 | name.sin_addr.s_addr = inet_addr( sAddr.getStr() ); | 59 | name.sin_addr.s_addr = DYNLOAD inet_addr( sAddr.getStr() ); | 
| 59 | #else | 60 | #else | 
| 60 | inet_aton( sAddr.getStr(), &name.sin_addr ); | 61 | inet_aton( sAddr.getStr(), &name.sin_addr ); | 
| 61 | #endif | 62 | #endif | 
| @@ -70,27 +71,29 @@ Bu::ServerSocket::~ServerSocket() | |||
| 70 | void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) | 71 | void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) | 
| 71 | { | 72 | { | 
| 72 | /* Create the socket. */ | 73 | /* Create the socket. */ | 
| 73 | nServer = socket( PF_INET, SOCK_STREAM, 0 ); | 74 | nServer = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); | 
| 75 | |||
| 74 | if( nServer < 0 ) | 76 | if( nServer < 0 ) | 
| 75 | { | 77 | { | 
| 76 | throw Bu::ServerSocketException("Couldn't create a listen socket."); | 78 | throw Bu::ServerSocketException("Couldn't create a listen socket."); | 
| 77 | } | 79 | } | 
| 78 | 80 | ||
| 79 | int opt = 1; | 81 | int opt = 1; | 
| 80 | setsockopt( | 82 | DYNLOAD setsockopt( | 
| 81 | nServer, | 83 | nServer, | 
| 82 | SOL_SOCKET, | 84 | SOL_SOCKET, | 
| 83 | SO_REUSEADDR, | 85 | SO_REUSEADDR, | 
| 84 | (char *)&opt, | 86 | (char *)&opt, | 
| 85 | sizeof( opt ) | 87 | sizeof( opt ) | 
| 86 | ); | 88 | ); | 
| 87 | 89 | ||
| 88 | if( bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) | 90 | if( DYNLOAD bind( | 
| 91 | nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) | ||
| 89 | { | 92 | { | 
| 90 | throw Bu::ServerSocketException("Couldn't bind to the listen socket."); | 93 | throw Bu::ServerSocketException("Couldn't bind to the listen socket."); | 
| 91 | } | 94 | } | 
| 92 | 95 | ||
| 93 | if( listen( nServer, nPoolSize ) < 0 ) | 96 | if( DYNLOAD listen( nServer, nPoolSize ) < 0 ) | 
| 94 | { | 97 | { | 
| 95 | throw Bu::ServerSocketException( | 98 | throw Bu::ServerSocketException( | 
| 96 | "Couldn't begin listening to the server socket." | 99 | "Couldn't begin listening to the server socket." | 
| @@ -116,20 +119,29 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) | |||
| 116 | xT.tv_sec = nTimeoutSec; | 119 | xT.tv_sec = nTimeoutSec; | 
| 117 | xT.tv_usec = nTimeoutUSec; | 120 | xT.tv_usec = nTimeoutUSec; | 
| 118 | 121 | ||
| 119 | if( TEMP_FAILURE_RETRY(select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) | 122 | if( TEMP_FAILURE_RETRY( | 
| 123 | DYNLOAD select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) | ||
| 120 | { | 124 | { | 
| 121 | throw Bu::ServerSocketException( | 125 | throw Bu::ServerSocketException( | 
| 122 | "Error scanning for new connections: %s", strerror( errno ) | 126 | "Error scanning for new connections: %s", strerror( errno ) | 
| 123 | ); | 127 | ); | 
| 124 | } | 128 | } | 
| 125 | 129 | ||
| 130 | #ifdef WIN32 | ||
| 131 | if( DynamicWinsock2::DYN_FD_ISSET( nServer, &fdRead ) ) | ||
| 132 | #else | ||
| 126 | if( FD_ISSET( nServer, &fdRead ) ) | 133 | if( FD_ISSET( nServer, &fdRead ) ) | 
| 134 | #endif | ||
| 127 | { | 135 | { | 
| 128 | struct sockaddr_in clientname; | 136 | struct sockaddr_in clientname; | 
| 129 | socklen_t size; | 137 | socklen_t size; | 
| 130 | int nClient; | 138 | int nClient; | 
| 131 | 139 | ||
| 132 | size = sizeof( clientname ); | 140 | size = sizeof( clientname ); | 
| 141 | #ifdef WIN32 | ||
| 142 | nClient = DYNLOAD accept( | ||
| 143 | nServer, (struct sockaddr *)&clientname, (int *)&size); | ||
| 144 | #else /* not-WIN32 */ | ||
| 133 | #ifdef __CYGWIN__ | 145 | #ifdef __CYGWIN__ | 
| 134 | nClient = ::accept( nServer, (struct sockaddr *)&clientname, | 146 | nClient = ::accept( nServer, (struct sockaddr *)&clientname, | 
| 135 | (int *)&size | 147 | (int *)&size | 
| @@ -141,6 +153,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) | |||
| 141 | nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size ); | 153 | nClient = ::accept( nServer, (struct sockaddr *)&clientname, &size ); | 
| 142 | #endif /* __APPLE__ */ | 154 | #endif /* __APPLE__ */ | 
| 143 | #endif /* __CYGWIN__ */ | 155 | #endif /* __CYGWIN__ */ | 
| 156 | #endif /* WIN32 */ | ||
| 144 | if( nClient < 0 ) | 157 | if( nClient < 0 ) | 
| 145 | { | 158 | { | 
| 146 | throw Bu::ServerSocketException( | 159 | throw Bu::ServerSocketException( | 
| @@ -175,7 +188,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) | |||
| 175 | // If iMode = 0, blocking is enabled; | 188 | // If iMode = 0, blocking is enabled; | 
| 176 | // If iMode != 0, non-blocking mode is enabled. | 189 | // If iMode != 0, non-blocking mode is enabled. | 
| 177 | u_long iMode = 1; | 190 | u_long iMode = 1; | 
| 178 | ioctlsocket(nClient, FIONBIO, &iMode); | 191 | DYNLOAD ioctlsocket(nClient, FIONBIO, &iMode); | 
| 179 | #endif | 192 | #endif | 
| 180 | } | 193 | } | 
| 181 | 194 | ||
| 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 ) | |||
| 44 | bActive = false; | 44 | bActive = false; | 
| 45 | 45 | ||
| 46 | /* Create the socket. */ | 46 | /* Create the socket. */ | 
| 47 | nSocket = socket( PF_INET, SOCK_STREAM, 0 ); | 47 | nSocket = DYNLOAD socket( PF_INET, SOCK_STREAM, 0 ); | 
| 48 | 48 | ||
| 49 | if( nSocket < 0 ) | 49 | if( nSocket < 0 ) | 
| 50 | { | 50 | { | 
| @@ -68,7 +68,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
| 68 | // If iMode = 0, blocking is enabled; | 68 | // If iMode = 0, blocking is enabled; | 
| 69 | // If iMode != 0, non-blocking mode is enabled. | 69 | // If iMode != 0, non-blocking mode is enabled. | 
| 70 | u_long iMode = 1; | 70 | u_long iMode = 1; | 
| 71 | ioctlsocket(nSocket, FIONBIO, &iMode); | 71 | DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); | 
| 72 | #endif | 72 | #endif | 
| 73 | 73 | ||
| 74 | /* Connect to the server. */ | 74 | /* Connect to the server. */ | 
| @@ -77,8 +77,8 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
| 77 | struct hostent *hostinfo; | 77 | struct hostent *hostinfo; | 
| 78 | 78 | ||
| 79 | xServerName.sin_family = AF_INET; | 79 | xServerName.sin_family = AF_INET; | 
| 80 | xServerName.sin_port = htons( nPort ); | 80 | xServerName.sin_port = DYNLOAD htons( nPort ); | 
| 81 | hostinfo = gethostbyname( sAddr.getStr() ); | 81 | hostinfo = DYNLOAD gethostbyname( sAddr.getStr() ); | 
| 82 | if (hostinfo == NULL) | 82 | if (hostinfo == NULL) | 
| 83 | { | 83 | { | 
| 84 | throw Bu::SocketException("Couldn't resolve hostname.\n"); | 84 | throw Bu::SocketException("Couldn't resolve hostname.\n"); | 
| @@ -88,7 +88,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
| 88 | 88 | ||
| 89 | //printf("Making actual connection..."); | 89 | //printf("Making actual connection..."); | 
| 90 | //fflush( stdout ); | 90 | //fflush( stdout ); | 
| 91 | connect( | 91 | DYNLOAD connect( | 
| 92 | nSocket, | 92 | nSocket, | 
| 93 | (struct sockaddr *)&xServerName, | 93 | (struct sockaddr *)&xServerName, | 
| 94 | sizeof(xServerName) | 94 | sizeof(xServerName) | 
| @@ -113,7 +113,7 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) | |||
| 113 | tv.tv_sec = nTimeout; | 113 | tv.tv_sec = nTimeout; | 
| 114 | tv.tv_usec = 0; | 114 | tv.tv_usec = 0; | 
| 115 | 115 | ||
| 116 | retval = select( nSocket+1, &rfds, &wfds, &efds, &tv ); | 116 | retval = DYNLOAD select( nSocket+1, &rfds, &wfds, &efds, &tv ); | 
| 117 | 117 | ||
| 118 | if( retval == 0 ) | 118 | if( retval == 0 ) | 
| 119 | { | 119 | { | 
| @@ -195,7 +195,12 @@ void Bu::Socket::read() | |||
| 195 | 195 | ||
| 196 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) | 196 | size_t Bu::Socket::read( void *pBuf, size_t nBytes ) | 
| 197 | { | 197 | { | 
| 198 | #ifdef WIN32 | ||
| 199 | int nRead = TEMP_FAILURE_RETRY( | ||
| 200 | DYNLOAD recv( nSocket, (char *) pBuf, nBytes, 0 ) ); | ||
| 201 | #else | ||
| 198 | int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); | 202 | int nRead = TEMP_FAILURE_RETRY( ::read( nSocket, pBuf, nBytes ) ); | 
| 203 | #endif | ||
| 199 | if( nRead < 0 ) | 204 | if( nRead < 0 ) | 
| 200 | { | 205 | { | 
| 201 | throw SocketException( SocketException::cRead, strerror(errno) ); | 206 | throw SocketException( SocketException::cRead, strerror(errno) ); | 
| @@ -213,35 +218,35 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, | |||
| 213 | FD_ZERO(&rfds); | 218 | FD_ZERO(&rfds); | 
| 214 | FD_SET(nSocket, &rfds); | 219 | FD_SET(nSocket, &rfds); | 
| 215 | 220 | ||
| 216 | #ifndef WIN32 | 221 | #ifdef WIN32 | 
| 222 | DWORD dwStart = GetTickCount(); | ||
| 223 | uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); | ||
| 224 | DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; | ||
| 225 | #else | ||
| 217 | struct timeval nt, ct; | 226 | struct timeval nt, ct; | 
| 218 | gettimeofday( &nt, NULL ); | 227 | gettimeofday( &nt, NULL ); | 
| 219 | nt.tv_sec += nSec; | 228 | nt.tv_sec += nSec; | 
| 220 | nt.tv_usec += nUSec; | 229 | nt.tv_usec += nUSec; | 
| 221 | #else | ||
| 222 | DWORD dwStart = GetTickCount(); | ||
| 223 | uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); | ||
| 224 | DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; | ||
| 225 | #endif | 230 | #endif | 
| 226 | 231 | ||
| 227 | for(;;) | 232 | for(;;) | 
| 228 | { | 233 | { | 
| 229 | tv.tv_sec = nSec; | 234 | tv.tv_sec = nSec; | 
| 230 | tv.tv_usec = nUSec; | 235 | tv.tv_usec = nUSec; | 
| 231 | select( nSocket+1, &rfds, NULL, NULL, &tv ); | 236 | DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); | 
| 232 | nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); | 237 | nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); | 
| 233 | if( nRead >= nBytes ) | 238 | if( nRead >= nBytes ) | 
| 234 | break; | 239 | break; | 
| 235 | #ifndef WIN32 | 240 | #ifdef WIN32 | 
| 241 | DWORD dwNow = GetTickCount(); | ||
| 242 | if( dwNow > dwEnd ) | ||
| 243 | break; | ||
| 244 | #else | ||
| 236 | gettimeofday( &ct, NULL ); | 245 | gettimeofday( &ct, NULL ); | 
| 237 | if( (ct.tv_sec > nt.tv_sec) || | 246 | if( (ct.tv_sec > nt.tv_sec) || | 
| 238 | (ct.tv_sec == nt.tv_sec && | 247 | (ct.tv_sec == nt.tv_sec && | 
| 239 | ct.tv_usec >= nt.tv_usec) ) | 248 | ct.tv_usec >= nt.tv_usec) ) | 
| 240 | break; | 249 | break; | 
| 241 | #else | ||
| 242 | DWORD dwNow = GetTickCount(); | ||
| 243 | if( dwNow > dwEnd ) | ||
| 244 | break; | ||
| 245 | #endif | 250 | #endif | 
| 246 | } | 251 | } | 
| 247 | return nRead; | 252 | return nRead; | 
| @@ -249,7 +254,12 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes, | |||
| 249 | 254 | ||
| 250 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) | 255 | size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) | 
| 251 | { | 256 | { | 
| 257 | #ifdef WIN32 | ||
| 258 | int nWrote = TEMP_FAILURE_RETRY( | ||
| 259 | DYNLOAD send( nSocket, (const char *) pBuf, nBytes, 0 ) ); | ||
| 260 | #else | ||
| 252 | int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); | 261 | int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); | 
| 262 | #endif | ||
| 253 | if( nWrote < 0 ) | 263 | if( nWrote < 0 ) | 
| 254 | { | 264 | { | 
| 255 | if( errno == EAGAIN ) return 0; | 265 | if( errno == EAGAIN ) return 0; | 
| @@ -267,35 +277,35 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32 | |||
| 267 | FD_ZERO(&wfds); | 277 | FD_ZERO(&wfds); | 
| 268 | FD_SET(nSocket, &wfds); | 278 | FD_SET(nSocket, &wfds); | 
| 269 | 279 | ||
| 270 | #ifndef WIN32 | 280 | #ifdef WIN32 | 
| 281 | DWORD dwStart = GetTickCount(); | ||
| 282 | uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); | ||
| 283 | DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; | ||
| 284 | #else | ||
| 271 | struct timeval nt, ct; | 285 | struct timeval nt, ct; | 
| 272 | gettimeofday( &nt, NULL ); | 286 | gettimeofday( &nt, NULL ); | 
| 273 | nt.tv_sec += nSec; | 287 | nt.tv_sec += nSec; | 
| 274 | nt.tv_usec += nUSec; | 288 | nt.tv_usec += nUSec; | 
| 275 | #else | ||
| 276 | DWORD dwStart = GetTickCount(); | ||
| 277 | uint64_t uOver = dwStart + ((nUSec / 1000) * (nSec * 1000)); | ||
| 278 | DWORD dwEnd = uOver>4294967295U?uOver-4294967295U:uOver; | ||
| 279 | #endif | 289 | #endif | 
| 280 | 290 | ||
| 281 | for(;;) | 291 | for(;;) | 
| 282 | { | 292 | { | 
| 283 | tv.tv_sec = nSec; | 293 | tv.tv_sec = nSec; | 
| 284 | tv.tv_usec = nUSec; | 294 | tv.tv_usec = nUSec; | 
| 285 | select( nSocket+1, NULL, &wfds, NULL, &tv ); | 295 | DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); | 
| 286 | nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); | 296 | nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); | 
| 287 | if( nWrote >= nBytes ) | 297 | if( nWrote >= nBytes ) | 
| 288 | break; | 298 | break; | 
| 289 | #ifndef WIN32 | 299 | #ifdef WIN32 | 
| 300 | DWORD dwNow = GetTickCount(); | ||
| 301 | if( dwNow > dwEnd ) | ||
| 302 | break; | ||
| 303 | #else | ||
| 290 | gettimeofday( &ct, NULL ); | 304 | gettimeofday( &ct, NULL ); | 
| 291 | if( (ct.tv_sec > nt.tv_sec) || | 305 | if( (ct.tv_sec > nt.tv_sec) || | 
| 292 | (ct.tv_sec == nt.tv_sec && | 306 | (ct.tv_sec == nt.tv_sec && | 
| 293 | ct.tv_usec >= nt.tv_usec) ) | 307 | ct.tv_usec >= nt.tv_usec) ) | 
| 294 | break; | 308 | break; | 
| 295 | #else | ||
| 296 | DWORD dwNow = GetTickCount(); | ||
| 297 | if( dwNow > dwEnd ) | ||
| 298 | break; | ||
| 299 | #endif | 309 | #endif | 
| 300 | } | 310 | } | 
| 301 | return nWrote; | 311 | return nWrote; | 
| @@ -332,13 +342,17 @@ bool Bu::Socket::canRead() | |||
| 332 | FD_ZERO(&rfds); | 342 | FD_ZERO(&rfds); | 
| 333 | FD_SET(nSocket, &rfds); | 343 | FD_SET(nSocket, &rfds); | 
| 334 | struct timeval tv = { 0, 0 }; | 344 | struct timeval tv = { 0, 0 }; | 
| 335 | int retval = select( nSocket+1, &rfds, NULL, NULL, &tv ); | 345 | int retval = DYNLOAD select( nSocket+1, &rfds, NULL, NULL, &tv ); | 
| 336 | if( retval == -1 ) | 346 | if( retval == -1 ) | 
| 337 | throw SocketException( | 347 | throw SocketException( | 
| 338 | SocketException::cBadRead, | 348 | SocketException::cBadRead, | 
| 339 | "Bad Read error" | 349 | "Bad Read error" | 
| 340 | ); | 350 | ); | 
| 351 | #ifdef WIN32 | ||
| 352 | if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &rfds ) ) | ||
| 353 | #else | ||
| 341 | if( !FD_ISSET( nSocket, &rfds ) ) | 354 | if( !FD_ISSET( nSocket, &rfds ) ) | 
| 355 | #endif | ||
| 342 | return false; | 356 | return false; | 
| 343 | return true; | 357 | return true; | 
| 344 | } | 358 | } | 
| @@ -349,13 +363,17 @@ bool Bu::Socket::canWrite() | |||
| 349 | FD_ZERO(&wfds); | 363 | FD_ZERO(&wfds); | 
| 350 | FD_SET(nSocket, &wfds); | 364 | FD_SET(nSocket, &wfds); | 
| 351 | struct timeval tv = { 0, 0 }; | 365 | struct timeval tv = { 0, 0 }; | 
| 352 | int retval = select( nSocket+1, NULL, &wfds, NULL, &tv ); | 366 | int retval = DYNLOAD select( nSocket+1, NULL, &wfds, NULL, &tv ); | 
| 353 | if( retval == -1 ) | 367 | if( retval == -1 ) | 
| 354 | throw SocketException( | 368 | throw SocketException( | 
| 355 | SocketException::cBadRead, | 369 | SocketException::cBadRead, | 
| 356 | "Bad Read error" | 370 | "Bad Read error" | 
| 357 | ); | 371 | ); | 
| 372 | #ifdef WIN32 | ||
| 373 | if( !DynamicWinsock2::DYN_FD_ISSET( nSocket, &wfds ) ) | ||
| 374 | #else | ||
| 358 | if( !FD_ISSET( nSocket, &wfds ) ) | 375 | if( !FD_ISSET( nSocket, &wfds ) ) | 
| 376 | #endif | ||
| 359 | return false; | 377 | return false; | 
| 360 | return true; | 378 | return true; | 
| 361 | } | 379 | } | 
| @@ -403,7 +421,7 @@ void Bu::Socket::setBlocking( bool bBlocking ) | |||
| 403 | // socket based on the numerical value of iMode. | 421 | // socket based on the numerical value of iMode. | 
| 404 | // If iMode = 0, blocking is enabled; | 422 | // If iMode = 0, blocking is enabled; | 
| 405 | // If iMode != 0, non-blocking mode is enabled. | 423 | // If iMode != 0, non-blocking mode is enabled. | 
| 406 | ioctlsocket(nSocket, FIONBIO, &iMode); | 424 | DYNLOAD ioctlsocket(nSocket, FIONBIO, &iMode); | 
| 407 | #endif | 425 | #endif | 
| 408 | } | 426 | } | 
| 409 | 427 | ||
| @@ -416,20 +434,20 @@ bool Bu::Socket::isOpen() | |||
| 416 | return bActive; | 434 | return bActive; | 
| 417 | } | 435 | } | 
| 418 | 436 | ||
| 419 | //#ifdef WIN32 | ||
| 420 | // typedef int socklen_t; | ||
| 421 | //#endif | ||
| 422 | |||
| 423 | void Bu::Socket::setAddress() | 437 | void Bu::Socket::setAddress() | 
| 424 | { | 438 | { | 
| 425 | struct sockaddr_in addr; | 439 | struct sockaddr_in addr; | 
| 426 | socklen_t len = sizeof(addr); | 440 | socklen_t len = sizeof(addr); | 
| 427 | addr.sin_family = AF_INET; | 441 | addr.sin_family = AF_INET; | 
| 428 | // getsockname( nSocket, (sockaddr *)(&addr), &len ); | 442 | // getsockname( nSocket, (sockaddr *)(&addr), &len ); | 
| 429 | getpeername( nSocket, (sockaddr *)(&addr), &len ); | 443 | DYNLOAD getpeername( nSocket, (sockaddr *)(&addr), &len ); | 
| 444 | #ifdef WIN32 | ||
| 445 | DYNLOAD inet_ntoa( sAddress, addr.sin_addr ); | ||
| 446 | #else | ||
| 430 | char buf[150]; | 447 | char buf[150]; | 
| 431 | sprintf( buf, "%s", inet_ntoa( addr.sin_addr ) ); | 448 | sprintf( buf, "%s", inet_ntoa( addr.sin_addr ) ); | 
| 432 | sAddress = buf; | 449 | sAddress = buf; | 
| 450 | #endif | ||
| 433 | } | 451 | } | 
| 434 | 452 | ||
| 435 | Bu::FString Bu::Socket::getAddress() const | 453 | 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 @@ | |||
| 1 | #include "win32_compatibility.h" | ||
| 2 | |||
| 3 | #ifdef WIN32 | ||
| 4 | |||
| 5 | typedef char * (__cdecl *FNDEF_DYN_inet_ntoa)( struct in_addr ); | ||
| 6 | void DynamicWinsock2::inet_ntoa( Bu::FString &out, struct in_addr addr_in ) | ||
| 7 | { | ||
| 8 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 9 | if( Ws2_32 != NULL ) | ||
| 10 | { | ||
| 11 | FNDEF_DYN_inet_ntoa fn = (FNDEF_DYN_inet_ntoa) | ||
| 12 | GetProcAddress( Ws2_32, "inet_ntoa" ); | ||
| 13 | if( fn != NULL ) | ||
| 14 | out = (fn)( addr_in ); | ||
| 15 | |||
| 16 | //We will let windows clean up our dll imports on exit | ||
| 17 | //FreeLibrary( Ws2_32 ); | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | typedef unsigned long (__cdecl *FNDEF_DYN_inet_addr)( const char * ); | ||
| 22 | unsigned long DynamicWinsock2::inet_addr( const char *s_in ) | ||
| 23 | { | ||
| 24 | unsigned long out = 0; | ||
| 25 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 26 | if( Ws2_32 != NULL ) | ||
| 27 | { | ||
| 28 | FNDEF_DYN_inet_addr fn = (FNDEF_DYN_inet_addr) | ||
| 29 | GetProcAddress( Ws2_32, "inet_addr" ); | ||
| 30 | if( fn != NULL ) | ||
| 31 | out = (fn)( s_in ); | ||
| 32 | } | ||
| 33 | return out; | ||
| 34 | } | ||
| 35 | |||
| 36 | typedef int (__cdecl *FNDEF_DYN_select)( | ||
| 37 | int nfds,fd_set*,fd_set*,fd_set*,const struct timeval*); | ||
| 38 | int DynamicWinsock2::select(int nfds, fd_set *readfds, fd_set *writefds, | ||
| 39 | fd_set *exceptfds, const struct timeval *timeout) | ||
| 40 | { | ||
| 41 | int out = 0; | ||
| 42 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 43 | if( Ws2_32 != NULL ) | ||
| 44 | { | ||
| 45 | FNDEF_DYN_select fn = (FNDEF_DYN_select) | ||
| 46 | GetProcAddress( Ws2_32, "select" ); | ||
| 47 | if( fn != NULL ) | ||
| 48 | out = (fn)( nfds, readfds, writefds, exceptfds, timeout ); | ||
| 49 | } | ||
| 50 | return out; | ||
| 51 | } | ||
| 52 | |||
| 53 | typedef SOCKET (__cdecl *FNDEF_DYN_socket)(int,int,int); | ||
| 54 | SOCKET DynamicWinsock2::socket(int domain, int type, int protocol) | ||
| 55 | { | ||
| 56 | SOCKET out = 0; | ||
| 57 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 58 | if( Ws2_32 != NULL ) | ||
| 59 | { | ||
| 60 | FNDEF_DYN_socket fn = (FNDEF_DYN_socket) | ||
| 61 | GetProcAddress( Ws2_32, "socket" ); | ||
| 62 | if( fn != NULL ) | ||
| 63 | out = (fn)( domain, type, protocol ); | ||
| 64 | } | ||
| 65 | return out; | ||
| 66 | } | ||
| 67 | |||
| 68 | typedef int (__cdecl *FNDEF_DYN_ioctlsocket)(SOCKET,long,u_long *); | ||
| 69 | int DynamicWinsock2::ioctlsocket(SOCKET s, long cmd, u_long *argp) | ||
| 70 | { | ||
| 71 | int out = 0; | ||
| 72 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 73 | if( Ws2_32 != NULL ) | ||
| 74 | { | ||
| 75 | FNDEF_DYN_ioctlsocket fn = (FNDEF_DYN_ioctlsocket) | ||
| 76 | GetProcAddress( Ws2_32, "ioctlsocket" ); | ||
| 77 | if( fn != NULL ) | ||
| 78 | out = (fn)( s, cmd, argp ); | ||
| 79 | } | ||
| 80 | return out; | ||
| 81 | } | ||
| 82 | |||
| 83 | typedef u_short (__cdecl *FNDEF_DYN_htons)(u_short); | ||
| 84 | u_short DynamicWinsock2::htons(u_short in) | ||
| 85 | { | ||
| 86 | u_short out = 0; | ||
| 87 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 88 | if( Ws2_32 != NULL ) | ||
| 89 | { | ||
| 90 | FNDEF_DYN_htons fn = (FNDEF_DYN_htons) | ||
| 91 | GetProcAddress( Ws2_32, "htons" ); | ||
| 92 | if( fn != NULL ) | ||
| 93 | out = (fn)( in ); | ||
| 94 | } | ||
| 95 | return out; | ||
| 96 | } | ||
| 97 | |||
| 98 | typedef u_long (__cdecl *FNDEF_DYN_htonl)(u_long); | ||
| 99 | u_long DynamicWinsock2::htonl(u_long in) | ||
| 100 | { | ||
| 101 | u_long out = 0; | ||
| 102 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 103 | if( Ws2_32 != NULL ) | ||
| 104 | { | ||
| 105 | FNDEF_DYN_htonl fn = (FNDEF_DYN_htonl) | ||
| 106 | GetProcAddress( Ws2_32, "htonl" ); | ||
| 107 | if( fn != NULL ) | ||
| 108 | out = (fn)( in ); | ||
| 109 | } | ||
| 110 | return out; | ||
| 111 | } | ||
| 112 | |||
| 113 | typedef struct hostent * (__cdecl *FNDEF_DYN_gethostbyname)(const char *); | ||
| 114 | struct hostent *DynamicWinsock2::gethostbyname(const char *name) | ||
| 115 | { | ||
| 116 | hostent *out = NULL; | ||
| 117 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 118 | if( Ws2_32 != NULL ) | ||
| 119 | { | ||
| 120 | FNDEF_DYN_gethostbyname fn = (FNDEF_DYN_gethostbyname) | ||
| 121 | GetProcAddress( Ws2_32, "gethostbyname" ); | ||
| 122 | if( fn != NULL ) | ||
| 123 | out = (fn)( name ); | ||
| 124 | } | ||
| 125 | return out; | ||
| 126 | } | ||
| 127 | |||
| 128 | typedef int (__cdecl *FNDEF_DYN_connect)(SOCKET,const struct sockaddr*,int); | ||
| 129 | int DynamicWinsock2::connect( | ||
| 130 | SOCKET s, const struct sockaddr *serv_addr, int addrlen) | ||
| 131 | { | ||
| 132 | int out = 0; | ||
| 133 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 134 | if( Ws2_32 != NULL ) | ||
| 135 | { | ||
| 136 | FNDEF_DYN_connect fn = (FNDEF_DYN_connect) | ||
| 137 | GetProcAddress( Ws2_32, "connect" ); | ||
| 138 | if( fn != NULL ) | ||
| 139 | out = (fn)( s, serv_addr, addrlen ); | ||
| 140 | } | ||
| 141 | return out; | ||
| 142 | } | ||
| 143 | |||
| 144 | typedef int (__cdecl *FNDEF_DYN_getpeername)(SOCKET,struct sockaddr*,int*); | ||
| 145 | int DynamicWinsock2::getpeername(SOCKET s, struct sockaddr *name, int *namelen) | ||
| 146 | { | ||
| 147 | int out = 0; | ||
| 148 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 149 | if( Ws2_32 != NULL ) | ||
| 150 | { | ||
| 151 | FNDEF_DYN_getpeername fn = (FNDEF_DYN_getpeername) | ||
| 152 | GetProcAddress( Ws2_32, "getpeername" ); | ||
| 153 | if( fn != NULL ) | ||
| 154 | out = (fn)( s, name, namelen ); | ||
| 155 | } | ||
| 156 | return out; | ||
| 157 | } | ||
| 158 | |||
| 159 | typedef int (__cdecl *FNDEF_DYN_setsockopt)(SOCKET,int,int,const char*,int); | ||
| 160 | int DynamicWinsock2::setsockopt(SOCKET s, int level, int optname, | ||
| 161 | const char *optval, int optlen) | ||
| 162 | { | ||
| 163 | int out = 0; | ||
| 164 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 165 | if( Ws2_32 != NULL ) | ||
| 166 | { | ||
| 167 | FNDEF_DYN_setsockopt fn = (FNDEF_DYN_setsockopt) | ||
| 168 | GetProcAddress( Ws2_32, "setsockopt" ); | ||
| 169 | if( fn != NULL ) | ||
| 170 | out = (fn)( s, level, optname, optval, optlen ); | ||
| 171 | } | ||
| 172 | return out; | ||
| 173 | } | ||
| 174 | |||
| 175 | typedef int (__cdecl *FNDEF_DYN_bind)(SOCKET,const struct sockaddr*,int); | ||
| 176 | int DynamicWinsock2::bind(SOCKET s, const struct sockaddr *my_addr, int addrlen) | ||
| 177 | { | ||
| 178 | int out = 0; | ||
| 179 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 180 | if( Ws2_32 != NULL ) | ||
| 181 | { | ||
| 182 | FNDEF_DYN_bind fn = (FNDEF_DYN_bind) | ||
| 183 | GetProcAddress( Ws2_32, "bind" ); | ||
| 184 | if( fn != NULL ) | ||
| 185 | out = (fn)( s, my_addr, addrlen ); | ||
| 186 | } | ||
| 187 | return out; | ||
| 188 | } | ||
| 189 | |||
| 190 | typedef int (__cdecl *FNDEF_DYN_listen)(SOCKET,int); | ||
| 191 | int DynamicWinsock2::listen(SOCKET s, int backlog) | ||
| 192 | { | ||
| 193 | int out = 0; | ||
| 194 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 195 | if( Ws2_32 != NULL ) | ||
| 196 | { | ||
| 197 | FNDEF_DYN_listen fn = (FNDEF_DYN_listen) | ||
| 198 | GetProcAddress( Ws2_32, "listen" ); | ||
| 199 | if( fn != NULL ) | ||
| 200 | out = (fn)( s, backlog ); | ||
| 201 | } | ||
| 202 | return out; | ||
| 203 | } | ||
| 204 | |||
| 205 | typedef SOCKET (__cdecl *FNDEF_DYN_accept)(SOCKET,struct sockaddr*,int*); | ||
| 206 | SOCKET DynamicWinsock2::accept(SOCKET s, struct sockaddr *addr, int *addrlen) | ||
| 207 | { | ||
| 208 | SOCKET out = 0; | ||
| 209 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 210 | if( Ws2_32 != NULL ) | ||
| 211 | { | ||
| 212 | FNDEF_DYN_accept fn = (FNDEF_DYN_accept) | ||
| 213 | GetProcAddress( Ws2_32, "accept" ); | ||
| 214 | if( fn != NULL ) | ||
| 215 | out = (fn)( s, addr, addrlen ); | ||
| 216 | } | ||
| 217 | return out; | ||
| 218 | } | ||
| 219 | |||
| 220 | typedef int (__cdecl *FNDEF_DYN_recv)(SOCKET,char*,int,int); | ||
| 221 | int DynamicWinsock2::recv( SOCKET s, char *buf, int len, int flags ) | ||
| 222 | { | ||
| 223 | int out = 0; | ||
| 224 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 225 | if( Ws2_32 != NULL ) | ||
| 226 | { | ||
| 227 | FNDEF_DYN_recv fn = (FNDEF_DYN_recv) | ||
| 228 | GetProcAddress( Ws2_32, "recv" ); | ||
| 229 | if( fn != NULL ) | ||
| 230 | out = (fn)( s, buf, len, flags ); | ||
| 231 | } | ||
| 232 | return out; | ||
| 233 | } | ||
| 234 | |||
| 235 | typedef int (__cdecl *FNDEF_DYN_send)(SOCKET,const char*,int,int); | ||
| 236 | int DynamicWinsock2::send( SOCKET s, const char *buf, int len, int flags ) | ||
| 237 | { | ||
| 238 | int out = 0; | ||
| 239 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 240 | if( Ws2_32 != NULL ) | ||
| 241 | { | ||
| 242 | FNDEF_DYN_send fn = (FNDEF_DYN_send) | ||
| 243 | GetProcAddress( Ws2_32, "send" ); | ||
| 244 | if( fn != NULL ) | ||
| 245 | out = (fn)( s, buf, len, flags ); | ||
| 246 | } | ||
| 247 | return out; | ||
| 248 | } | ||
| 249 | |||
| 250 | typedef int (__cdecl *FNDEF_DYN__WSAFDIsSet)(SOCKET,fd_set*); | ||
| 251 | int DynamicWinsock2::DYN_FD_ISSET(SOCKET s, fd_set *set) | ||
| 252 | { | ||
| 253 | int out = 0; | ||
| 254 | HINSTANCE Ws2_32 = LoadLibrary(TEXT("Ws2_32")); | ||
| 255 | if( Ws2_32 != NULL ) | ||
| 256 | { | ||
| 257 | FNDEF_DYN__WSAFDIsSet fn = (FNDEF_DYN__WSAFDIsSet) | ||
| 258 | GetProcAddress( Ws2_32, "__WSAFDIsSet" ); | ||
| 259 | if( fn != NULL ) | ||
| 260 | out = (fn)( s, set ); | ||
| 261 | } | ||
| 262 | return out; | ||
| 263 | } | ||
| 264 | |||
| 265 | #endif | ||
| 266 | |||
| 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 | |||
| @@ -9,6 +9,15 @@ | |||
| 9 | #define WIN32_COMPATIBILITY__H | 9 | #define WIN32_COMPATIBILITY__H | 
| 10 | 10 | ||
| 11 | #ifdef WIN32 | 11 | #ifdef WIN32 | 
| 12 | #define DYNLOAD DynamicWinsock2:: | ||
| 13 | #else | ||
| 14 | #define DYNLOAD | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifdef WIN32 | ||
| 18 | |||
| 19 | #include <Winsock2.h> | ||
| 20 | #include "fstring.h" | ||
| 12 | 21 | ||
| 13 | #ifndef TEMP_FAILURE_RETRY | 22 | #ifndef TEMP_FAILURE_RETRY | 
| 14 | #define TEMP_FAILURE_RETRY(expression) \ | 23 | #define TEMP_FAILURE_RETRY(expression) \ | 
| @@ -19,9 +28,31 @@ | |||
| 19 | __result; })) | 28 | __result; })) | 
| 20 | #endif | 29 | #endif | 
| 21 | 30 | ||
| 22 | //__extension__ typedef unsigned int socklen_t; | ||
| 23 | __extension__ typedef int socklen_t; | 31 | __extension__ typedef int socklen_t; | 
| 24 | 32 | ||
| 33 | namespace DynamicWinsock2 | ||
| 34 | { | ||
| 35 | void inet_ntoa( Bu::FString &out, struct in_addr addr_in ); | ||
| 36 | unsigned long inet_addr( const char *s_in ); | ||
| 37 | int select(int nfds, fd_set *readfds, fd_set *writefds, | ||
| 38 | fd_set *exceptfds, const struct timeval *timeout); | ||
| 39 | SOCKET socket(int domain, int type, int protocol); | ||
| 40 | int ioctlsocket(SOCKET s, long cmd, u_long *argp); | ||
| 41 | u_short htons(u_short in); | ||
| 42 | u_long htonl(u_long in); | ||
| 43 | struct hostent *gethostbyname(const char *name); | ||
| 44 | int connect(SOCKET s, const struct sockaddr *serv_addr, int addrlen); | ||
| 45 | int getpeername(SOCKET s, struct sockaddr *name, int *namelen); | ||
| 46 | int setsockopt(SOCKET s, int level, int optname, | ||
| 47 | const char *optval, int optlen); | ||
| 48 | int bind(SOCKET s, const struct sockaddr *my_addr, int addrlen); | ||
| 49 | int listen(SOCKET s, int backlog); | ||
| 50 | SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen); | ||
| 51 | int recv( SOCKET s, char *buf, int len, int flags ); | ||
| 52 | int send( SOCKET s, const char *buf, int len, int flags ); | ||
| 53 | int DYN_FD_ISSET(SOCKET s, fd_set *set); | ||
| 54 | }; | ||
| 55 | |||
| 25 | #endif /* WIN32 */ | 56 | #endif /* WIN32 */ | 
| 26 | #endif | 57 | #endif | 
| 27 | 58 | ||
