X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1aa7b427f21877287adfb49395a209459320c044..b4866582826131342dd610fab2136df84f8fb974:/src/unix/gsocket.cpp diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index b4294370c1..1ea7b594e5 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -181,6 +181,9 @@ int _System soclose(int); # include "wx/unix/gsockunx.h" # include "wx/unix/private.h" # include "wx/gsocket.h" +#if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME)) +# include "wx/thread.h" +#endif #else # include "gsockunx.h" # include "gsocket.h" @@ -189,6 +192,175 @@ int _System soclose(int); # endif #endif /* __GSOCKET_STANDALONE__ */ +#if defined(HAVE_GETHOSTBYNAME) +static struct hostent * deepCopyHostent(struct hostent *h, + const struct hostent *he, + char *buffer, int size, int *err) +{ + memcpy(h, he, sizeof(struct hostent)); + int len = strlen(h->h_name); + if (len > size) + len = size - 1; + memcpy(buffer, h->h_name, len); + buffer[len] = '\0'; + h->h_name = buffer; + buffer += len + 1; + size -= len + 1; + len = h->h_length; + for (char **p = h->h_addr_list; *p != 0; p++) { + if (size < len){ + *err = ENOMEM; + return NULL; + } + memcpy(buffer, *p, len); + *p = buffer; + buffer += len; + size -= len; + } + for (char **q = h->h_aliases; size > 0 && *q != 0; q++){ + len = strlen(*q); + if (len > size) + len = size - 1; + memcpy(buffer, *q, len); + buffer[len] = '\0'; + *q = buffer; + buffer += len + 1; + size -= len + 1; + } + return h; +} +#endif + +struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h, + void *buffer, int size, int *err) + +{ + struct hostent *he = NULL; + *err = 0; +#if defined(HAVE_FUNC_GETHOSTBYNAME_R_6) + if (gethostbyname_r(hostname, h, (char*)buffer, size, &he, err)) + he = NULL; +#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5) + he = gethostbyname_r(hostname, h, (char*)buffer, size, err); +#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3) + if (gethostbyname_r(hostname, h, (struct hostent_data*) buffer)) + { + he = NULL; + *err = h_errno; + } + else + he = h; +#elif defined(HAVE_GETHOSTBYNAME) +#if wxUSE_THREADS + static wxMutex nameLock; + wxMutexLocker locker(nameLock); +#endif + he = gethostbyname(hostname); + if (!he) + *err = h_errno; + else + he = deepCopyHostent(h, he, (char*)buffer, size, err); +#endif + return he; +} + +struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size, + int proto, struct hostent *h, + void *buffer, int size, int *err) +{ + struct hostent *he = NULL; + *err = 0; +#if defined(HAVE_FUNC_GETHOSTBYNAME_R_6) + if (gethostbyaddr_r(addr_buf, buf_size, proto, h, + (char*)buffer, size, &he, err)) + he = NULL; +#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5) + he = gethostbyaddr_r(addr_buf, buf_size, proto, h, (char*)buffer, size, err); +#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3) + if (gethostbyaddr_r(addr_buf, buf_size, proto, h, + (struct hostent_data*) buffer)) + { + he = NULL; + *err = h_errno; + } + else + he = h; +#elif defined(HAVE_GETHOSTBYNAME) +#if wxUSE_THREADS + static wxMutex addrLock; + wxMutexLocker locker(addrLock); +#endif + he = gethostbyaddr(addr_buf, buf_size, proto); + if (!he) + *err = h_errno; + else + he = deepCopyHostent(h, he, (char*)buffer, size, err); +#endif + return he; +} + +#if defined(HAVE_GETHOSTBYNAME) +static struct servent * deepCopyServent(struct servent *s, + const struct servent *se, + char *buffer, int size) +{ + memcpy(s, se, sizeof(struct servent)); + int len = strlen(s->s_name); + if (len > size) + len = size - 1; + memcpy(buffer, s->s_name, len); + buffer[len] = '\0'; + s->s_name = buffer; + buffer += len + 1; + size -= len + 1; + len = strlen(s->s_proto); + if (len > size) + len = size - 1; + memcpy(buffer, s->s_proto, len); + buffer[len] = '\0'; + s->s_proto = buffer; + buffer += len + 1; + size -= len + 1; + for (char **q = s->s_aliases; size > 0 && *q != 0; q++){ + len = strlen(*q); + if (len > size) + len = size - 1; + memcpy(buffer, *q, len); + buffer[len] = '\0'; + *q = buffer; + buffer += len + 1; + size -= len + 1; + } + return s; +} +#endif + +struct servent *wxGetservbyname_r(const char *port, const char *protocol, + struct servent *serv, void *buffer, int size) +{ + struct servent *se = NULL; +#if defined(HAVE_FUNC_GETSERVBYNAME_R_6) + if (getservbyname_r(port, protocol, serv, (char*)buffer, size, &se)) + se = NULL; +#elif defined(HAVE_FUNC_GETSERVBYNAME_R_5) + se = getservbyname_r(port, protocol, serv, (char*)buffer, size); +#elif defined(HAVE_FUNC_GETSERVBYNAME_R_4) + if (getservbyname_r(port, protocol, serv, (struct servent_data*) buffer)) + se = NULL; + else + se = serv; +#elif defined(HAVE_GETSERVBYNAME) +#if wxUSE_THREADS + static wxMutex servLock; + wxMutexLocker locker(servLock); +#endif + se = getservbyname(port, protocol); + if (se) + se = deepCopyServent(serv, se, (char*)buffer, size); +#endif + return se; +} + /* debugging helpers */ #ifdef __GSOCKET_DEBUG__ # define GSocket_Debug(args) printf args @@ -1772,7 +1944,15 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname) struct in_addr *array_addr; /* It is a real name, we solve it */ - if ((he = gethostbyname(hostname)) == NULL) + struct hostent h; +#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3) + struct hostent_data buffer; +#else + char buffer[1024]; +#endif + int err; + he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err); + if (he == NULL) { /* Reset to invalid address */ addr->s_addr = INADDR_NONE; @@ -1822,11 +2002,14 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port, return GSOCK_INVPORT; } -#if defined(__WXPM__) && defined(__EMX__) - se = getservbyname(port, (char*)protocol); +#if defined(HAVE_FUNC_GETSERVBYNAME_R_4) + struct servent_data buffer; #else - se = getservbyname(port, protocol); + char buffer[1024]; #endif + struct servent serv; + se = wxGetservbyname_r(port, protocol, &serv, + (void*)&buffer, sizeof(buffer)); if (!se) { /* the cast to int suppresses compiler warnings about subscript having the @@ -1876,7 +2059,15 @@ GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t addr = (struct sockaddr_in *)address->m_addr; addr_buf = (char *)&(addr->sin_addr); - he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET); + struct hostent temphost; +#if defined(HAVE_FUNC_GETHOSTBYNAME_R_3) + struct hostent_data buffer; +#else + char buffer[1024]; +#endif + int err; + he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost, + (void*)&buffer, sizeof(buffer), &err); if (he == NULL) { address->m_error = GSOCK_NOHOST;