diff options
author | glx <glx@openttd.org> | 2009-04-03 14:01:45 +0000 |
---|---|---|
committer | glx <glx@openttd.org> | 2009-04-03 14:01:45 +0000 |
commit | 65d10e66f004de45a86eb9909171a65f448d227f (patch) | |
tree | bf76f148adf317820085bb59d98b1a7cdcea97d1 | |
parent | 5386fe1a1c0a9f04ba40e03d162c1641e0ebd1af (diff) | |
download | openttd-65d10e66f004de45a86eb9909171a65f448d227f.tar.xz |
(svn r15933) -Fix (r15920): mingw doesn't know getaddrinfo() and freeaddrinfo() either
-rw-r--r-- | src/network/core/address.cpp | 2 | ||||
-rw-r--r-- | src/network/core/os_abstraction.h | 76 |
2 files changed, 72 insertions, 6 deletions
diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 7d91aa9a4..016489001 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -88,7 +88,7 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, LoopProc fun int e = getaddrinfo(this->GetHostname(), port_name, &hints, &ai); if (e != 0) { - DEBUG(net, 0, "getaddrinfo failed: %s", gai_strerror(e)); + DEBUG(net, 0, "getaddrinfo failed: %s", FS2OTTD(gai_strerror(e))); return INVALID_SOCKET; } diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h index c54189e9e..58824d8b8 100644 --- a/src/network/core/os_abstraction.h +++ b/src/network/core/os_abstraction.h @@ -19,12 +19,20 @@ #include <ws2tcpip.h> #include <windows.h> +#define GET_LAST_ERROR() WSAGetLastError() +#define EWOULDBLOCK WSAEWOULDBLOCK +/* Windows has some different names for some types */ +typedef unsigned long in_addr_t; + #if !(defined(__MINGW32__) || defined(__CYGWIN__)) /* Windows has some different names for some types */ typedef SSIZE_T ssize_t; typedef int socklen_t; #else #include "../../win32.h" +#include "../../core/alloc_func.hpp" + +#define AI_ADDRCONFIG 0x00000400 // Resolution only if global address configured static inline int OTTDgetnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, DWORD hostlen, char *serv, DWORD servlen, int flags) { @@ -42,12 +50,70 @@ static inline int OTTDgetnameinfo(const struct sockaddr *sa, socklen_t salen, ch return 0; } #define getnameinfo OTTDgetnameinfo -#endif -#define GET_LAST_ERROR() WSAGetLastError() -#define EWOULDBLOCK WSAEWOULDBLOCK -/* Windows has some different names for some types */ -typedef unsigned long in_addr_t; +static inline int OTTDgetaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ + static int (WINAPI *getaddrinfo)(const char *, const char *, const struct addrinfo *, struct addrinfo **) = NULL; + static bool first_time = true; + + if (first_time) { + LoadLibraryList((Function*)&getaddrinfo, "ws2_32.dll\0getaddrinfo\0\0"); + first_time = false; + } + + if (getaddrinfo != NULL) return getaddrinfo(nodename, servname, hints, res); + + *res = NULL; + + in_addr_t ip = inet_addr(nodename); + if (ip == INADDR_NONE) { + struct hostent *he = gethostbyname(nodename); + if (he == NULL) return EAI_NONAME; + ip = (*(struct in_addr *)he->h_addr).s_addr; + } + + struct sockaddr_in *sin = CallocT<struct sockaddr_in>(1); + sin->sin_family = AF_INET; + sin->sin_port = htons(strtoul(servname, NULL, 10)); + sin->sin_addr.s_addr = ip; + + struct addrinfo *ai = CallocT<struct addrinfo>(1); + ai->ai_family = PF_INET; + ai->ai_addr = (struct sockaddr*)sin; + ai->ai_addrlen = sizeof(*sin); + ai->ai_socktype = hints->ai_socktype; + + *res = ai; + return 0; +} +#define getaddrinfo OTTDgetaddrinfo + +static inline void OTTDfreeaddrinfo(struct addrinfo *ai) +{ + static int (WINAPI *freeaddrinfo)(struct addrinfo *) = NULL; + static bool first_time = true; + + if (ai == NULL) return; + + if (first_time) { + LoadLibraryList((Function*)&freeaddrinfo, "ws2_32.dll\freeaddrinfo\0\0"); + first_time = false; + } + + if (freeaddrinfo != NULL) { + freeaddrinfo(ai); + return; + } + + do { + struct addrinfo *next = ai->ai_next; + free(ai->ai_addr); + free(ai); + ai = next; + } while(ai != NULL); +} +#define freeaddrinfo OTTDfreeaddrinfo +#endif /* __MINGW32__ && __CYGWIN__ */ #endif /* WIN32 */ /* UNIX stuff */ |