From: Stefan Neis Date: Tue, 3 Jan 2006 16:36:20 +0000 (+0000) Subject: Added thread-safe wrappers for get{host,serv}by{name,addr} to replace the X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/71b4a9b87889824ce3cb6406e040be69e5b5e0f4?ds=sidebyside Added thread-safe wrappers for get{host,serv}by{name,addr} to replace the currently still used unsafe versions once possible compilation problems are sorted out. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index b4294370c1..31a7c6e36c 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; + *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; + *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; +#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