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 /src | |
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-- | 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 |
4 files changed, 382 insertions, 54 deletions
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 | ||