summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid <david@xagasoft.com>2008-10-27 16:07:50 +0000
committerDavid <david@xagasoft.com>2008-10-27 16:07:50 +0000
commit61edfe804eb1a1dbf96fcdf2f1b700ed1cfa7ff9 (patch)
tree530a0d86ca1043dbc04cd7513bc5dd65768a266d /src
parentf7e8658f2274044bb452492b1af7e2cd5f82082c (diff)
downloadlibbu++-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 'src')
-rw-r--r--src/serversocket.cpp47
-rw-r--r--src/socket.cpp90
-rw-r--r--src/win32_compatibility.cpp266
-rw-r--r--src/win32_compatibility.h33
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()
70void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) 71void 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
196size_t Bu::Socket::read( void *pBuf, size_t nBytes ) 196size_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
250size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) 255size_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
423void Bu::Socket::setAddress() 437void 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
435Bu::FString Bu::Socket::getAddress() const 453Bu::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
5typedef char * (__cdecl *FNDEF_DYN_inet_ntoa)( struct in_addr );
6void 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
21typedef unsigned long (__cdecl *FNDEF_DYN_inet_addr)( const char * );
22unsigned 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
36typedef int (__cdecl *FNDEF_DYN_select)(
37 int nfds,fd_set*,fd_set*,fd_set*,const struct timeval*);
38int 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
53typedef SOCKET (__cdecl *FNDEF_DYN_socket)(int,int,int);
54SOCKET 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
68typedef int (__cdecl *FNDEF_DYN_ioctlsocket)(SOCKET,long,u_long *);
69int 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
83typedef u_short (__cdecl *FNDEF_DYN_htons)(u_short);
84u_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
98typedef u_long (__cdecl *FNDEF_DYN_htonl)(u_long);
99u_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
113typedef struct hostent * (__cdecl *FNDEF_DYN_gethostbyname)(const char *);
114struct 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
128typedef int (__cdecl *FNDEF_DYN_connect)(SOCKET,const struct sockaddr*,int);
129int 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
144typedef int (__cdecl *FNDEF_DYN_getpeername)(SOCKET,struct sockaddr*,int*);
145int 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
159typedef int (__cdecl *FNDEF_DYN_setsockopt)(SOCKET,int,int,const char*,int);
160int 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
175typedef int (__cdecl *FNDEF_DYN_bind)(SOCKET,const struct sockaddr*,int);
176int 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
190typedef int (__cdecl *FNDEF_DYN_listen)(SOCKET,int);
191int 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
205typedef SOCKET (__cdecl *FNDEF_DYN_accept)(SOCKET,struct sockaddr*,int*);
206SOCKET 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
220typedef int (__cdecl *FNDEF_DYN_recv)(SOCKET,char*,int,int);
221int 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
235typedef int (__cdecl *FNDEF_DYN_send)(SOCKET,const char*,int,int);
236int 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
250typedef int (__cdecl *FNDEF_DYN__WSAFDIsSet)(SOCKET,fd_set*);
251int 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
33namespace 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