summaryrefslogtreecommitdiff
path: root/network_io
diff options
context:
space:
mode:
authorBojan Smojver <bojan@apache.org>2008-05-29 01:57:16 +0000
committerBojan Smojver <bojan@apache.org>2008-05-29 01:57:16 +0000
commit9f935aaede411677912713e6ca8ce2ccbb210cac (patch)
tree6cc6bb9ee6d4b23e7db6490bfddc35a06910a95c /network_io
parent7c72118c012ae6caf1870b36c35c20b8634c127c (diff)
downloadapr-9f935aaede411677912713e6ca8ce2ccbb210cac.tar.gz
Fix PR44367.
Caveats: - no idea if IBM's proprietary OSes actually have thread-safe version of getservbyname() function, just assumed that by looking at other similar functions being marked safe in APR detection code - works on Linux (Fedora 9, i.e. glibc2) Use thread safe versions of getservbyname(). git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@661178 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io')
-rw-r--r--network_io/unix/sockaddr.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c
index 31a0eb5be..4e79f8934 100644
--- a/network_io/unix/sockaddr.c
+++ b/network_io/unix/sockaddr.c
@@ -705,17 +705,63 @@ APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
APR_DECLARE(apr_status_t) apr_getservbyname(apr_sockaddr_t *sockaddr,
const char *servname)
{
+#if APR_HAS_THREADS && !defined(GETSERVBYNAME_IS_THREAD_SAFE) && \
+ defined(HAVE_GETSERVBYNAME_R) && \
+ (defined(GETSERVBYNAME_R_GLIBC2) || defined(GETSERVBYNAME_R_SOLARIS) || \
+ defined(GETSERVBYNAME_R_OSF1))
+ struct servent se;
+#if defined(GETSERVBYNAME_R_OSF1)
+ struct servent_data sed;
+
+ memset(&sed, 0, sizeof(sed)); /* must zero fill before use */
+#else
+#if defined(GETSERVBYNAME_R_GLIBC2)
+ struct servent *res;
+#endif
+ char buf[1024];
+#endif
+#else
struct servent *se;
+#endif
if (servname == NULL)
return APR_EINVAL;
+#if APR_HAS_THREADS && !defined(GETSERVBYNAME_IS_THREAD_SAFE) && \
+ defined(HAVE_GETSERVBYNAME_R) && \
+ (defined(GETSERVBYNAME_R_GLIBC2) || defined(GETSERVBYNAME_R_SOLARIS) || \
+ defined(GETSERVBYNAME_R_OSF1))
+#if defined(GETSERVBYNAME_R_GLIBC2)
+ if (getservbyname_r(servname, NULL,
+ &se, buf, sizeof(buf), &res) == 0 && res != NULL) {
+ sockaddr->port = ntohs(res->s_port);
+ sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
+ sockaddr->sa.sin.sin_port = res->s_port;
+ return APR_SUCCESS;
+ }
+#elif defined(GETSERVBYNAME_R_SOLARIS)
+ if (getservbyname_r(servname, NULL, &se, buf, sizeof(buf)) != NULL) {
+ sockaddr->port = ntohs(se.s_port);
+ sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
+ sockaddr->sa.sin.sin_port = se.s_port;
+ return APR_SUCCESS;
+ }
+#elif defined(GETSERVBYNAME_R_OSF1)
+ if (getservbyname_r(servname, NULL, &se, &sed) == 0) {
+ sockaddr->port = ntohs(se.s_port);
+ sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
+ sockaddr->sa.sin.sin_port = se.s_port;
+ return APR_SUCCESS;
+ }
+#endif
+#else
if ((se = getservbyname(servname, NULL)) != NULL){
sockaddr->port = ntohs(se->s_port);
sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
sockaddr->sa.sin.sin_port = se->s_port;
return APR_SUCCESS;
}
+#endif
return APR_ENOENT;
}