summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2001-07-31 02:10:11 +0000
committerjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2001-07-31 02:10:11 +0000
commit691d2acacdb354089057eb195001a0e27f1afb4c (patch)
treee7cdf474470603a01b7b04aa49e0cc653f52db1b
parentdd23d6460537c44d641d821fa1a633c23b45911c (diff)
downloadlibapr-691d2acacdb354089057eb195001a0e27f1afb4c.tar.gz
Support the AIX, glibc2, and Solaris variants of gethostby{name|addr}_r.
Use gethostbyaddr_r function when available. The AIX gurus will have to test this to make sure I got their prototype right. This compiles on Solaris. Submitted by: Sterling Hughes <sterling@designmultimedia.com> (Modified by Justin) Reviewed by: Justin Erenkrantz git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@62063 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES4
-rw-r--r--acconfig.h1
-rw-r--r--build/apr_network.m463
-rw-r--r--configure.in9
-rw-r--r--network_io/unix/sa_common.c60
5 files changed, 131 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 75979797e..89762cc74 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
Changes with APR b1
+ *) Support the AIX, glibc2, and Solaris variants of gethostby{name|addr}_r.
+ Use gethostbyaddr_r function when available.
+ [Sterling Hughes <sterling@designmultimedia.com>]
+
*) Add new socket option, APR_INCOMPLETE_READ, that should be
set when you expect the first non-blocking read to fail with
EAGAIN. Setting APR_INCOMPLETE_READ prior to calling apr_read
diff --git a/acconfig.h b/acconfig.h
index 89909514e..22047e545 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -24,6 +24,7 @@
#undef READDIR_IS_THREAD_SAFE
#undef GETHOSTBYNAME_IS_THREAD_SAFE
+#undef GETHOSTBYADDR_IS_THREAD_SAFE
#undef NEED_RLIM_T
#undef USEBCOPY
diff --git a/build/apr_network.m4 b/build/apr_network.m4
index ecbf36e3d..e9278d661 100644
--- a/build/apr_network.m4
+++ b/build/apr_network.m4
@@ -145,6 +145,69 @@ if test "$ac_cv_gethostbyname_nas" = "yes"; then
fi
])
+dnl
+dnl Checks the definition of gethostbyname_r and gethostbyaddr_r
+dnl which are different for glibc, solaris and assorted other operating
+dnl systems
+dnl
+dnl Note that this test is executed too early to see if we have all of
+dnl the headers.
+AC_DEFUN(APR_CHECK_GETHOSTBYNAME_R_STYLE,[
+
+dnl Try and compile a glibc2 gethostbyname_r piece of code, and set the
+dnl style of the routines to glibc2 on success
+AC_CACHE_CHECK([style of gethostbyname_r routine], ac_cv_gethostbyname_r_style,
+APR_TRY_COMPILE_NO_WARNING([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+],[
+int tmp = gethostbyname_r((const char *) 0, (struct hostent *) 0,
+ (char *) 0, 0, (struct hostent **) 0, &tmp);
+], ac_cv_gethostbyname_r_style=glibc2, ac_cv_gethostbyname_r_style=none))
+
+if test "$ac_cv_gethostbyname_r_style" = "glibc2"; then
+ AC_DEFINE(GETHOSTBYNAME_R_GLIBC2, 1, [Define if gethostbyname_r has the glibc style])
+fi
+
+AC_CACHE_CHECK([3rd argument to the gethostbyname_r routines], ac_cv_gethostbyname_r_arg,
+APR_TRY_COMPILE_NO_WARNING([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+],[
+int tmp = gethostbyname_r((const char *) 0, (struct hostent *) 0,
+ (struct hostent_data *) 0);],
+ac_cv_gethostbyname_r_arg=hostent_data, ac_cv_gethostbyname_r_arg=char))
+
+if test "$ac_cv_gethostbyname_r_arg" = "hostent_data"; then
+ AC_DEFINE(GETHOSTBYNAME_R_HOSTENT_DATA, 1, [Define if gethostbyname_r has the hostent_data for the third argument])
+fi
+])
dnl
dnl see if TCP_NODELAY setting is inherited from listening sockets
diff --git a/configure.in b/configure.in
index a33d48500..656f3271b 100644
--- a/configure.in
+++ b/configure.in
@@ -338,11 +338,13 @@ fi
ac_cv_define_READDIR_IS_THREAD_SAFE=no
ac_cv_define_GETHOSTBYNAME_IS_THREAD_SAFE=no
+ac_cv_define_GETHOSTBYADDR_IS_THREAD_SAFE=no
if test "$threads" = "1"; then
echo "APR will use threads"
AC_CHECK_LIB(c_r, readdir, AC_DEFINE(READDIR_IS_THREAD_SAFE))
AC_CHECK_LIB(c_r, gethostbyname, AC_DEFINE(GETHOSTBYNAME_IS_THREAD_SAFE))
- AC_CHECK_FUNCS(gethostbyname_r)
+ AC_CHECK_LIB(c_r, gethostbyaddr, AC_DEFINE(GETHOSTBYADDR_IS_THREAD_SAFE))
+ AC_CHECK_FUNCS(gethostbyname_r gethostbyaddr_r)
else
echo "APR will be non-threaded"
fi
@@ -1196,6 +1198,11 @@ APR_CHECK_SOCKADDR_SA_LEN
APR_CHECK_GETHOSTBYNAME_NAS
+dnl Check the types only if we have gethostbyname_r
+if test "$ac_cv_func_gethostbyname_r" = "yes"; then
+ APR_CHECK_GETHOSTBYNAME_R_STYLE
+fi
+
APR_CHECK_TCP_NODELAY_INHERITED
dnl # Look for a way of corking TCP...
diff --git a/network_io/unix/sa_common.c b/network_io/unix/sa_common.c
index 644906acb..0907ab8a1 100644
--- a/network_io/unix/sa_common.c
+++ b/network_io/unix/sa_common.c
@@ -394,7 +394,11 @@ APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
int curaddr;
#if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
+#ifdef GETHOSTBYNAME_R_HOSTENT_DATA
+ struct hostent_data hd;
+#else
char tmp[GETHOSTBYNAME_BUFLEN];
+#endif
int hosterror;
struct hostent hs;
#endif
@@ -415,8 +419,19 @@ APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
#endif
#if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
- hp = gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
+#if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
+ /* AIX, HP/UX, D/UX et alia */
+ gethostbyname_r(hostname, &hs, &hd);
+ hp = &hs;
+#elif defined(GETHOSTBYNAME_R_GLIBC2)
+ /* Linux glibc2+ */
+ gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
+ &hp, &hosterror);
+#else
+ /* Solaris, Irix et alia */
+ hp = gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
&hosterror);
+#endif
#else
hp = gethostbyname(hostname);
#endif
@@ -426,9 +441,13 @@ APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
apr_get_netos_error();
#elif APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
+#ifdef GETHOSTBYNAME_R_HOSTENT_DATA
+ return (h_errno + APR_OS_START_SYSERR);
+#else
/* If you see ERANGE, that means GETHOSBYNAME_BUFLEN needs to be
* bumped. */
return (hosterror + APR_OS_START_SYSERR);
+#endif
#else
return (h_errno + APR_OS_START_SYSERR);
#endif
@@ -502,17 +521,48 @@ APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
tmphostname);
return APR_SUCCESS;
#else
+#if APR_HAS_THREADS && !defined(GETHOSTBYADDR_IS_THREAD_SAFE) && \
+ defined(HAVE_GETHOSTBYADDR_R) && !defined(BEOS)
+#ifdef GETHOSTBYNAME_R_HOSTENT_DATA
+ struct hostent_data hd;
+#else
+ char tmp[GETHOSTBYNAME_BUFLEN];
+#endif
+ int hosterror;
+ struct hostent hs, *hptr;
+
+#if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
+ /* AIX, HP/UX, D/UX et alia */
+ gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+ sizeof(struct in_addr), AF_INET, &hs, &hd);
+ hptr = &hs;
+#elif defined(GETHOSTBYNAME_R_GLIBC2)
+ /* Linux glibc2+ */
+ gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+ sizeof(struct in_addr), AF_INET,
+ &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hptr, &hosterror);
+#else
+ /* Solaris, Irix et alia */
+ hptr = gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
+ sizeof(struct in_addr), AF_INET,
+ &hs, tmp, GETHOSTBYNAME_BUFLEN, &hosterror);
+#endif
+#else
struct hostent *hptr;
-
hptr = gethostbyaddr((char *)&sockaddr->sa.sin.sin_addr,
- sizeof(struct in_addr),
- AF_INET);
+ sizeof(struct in_addr), AF_INET);
+#endif
+
if (hptr) {
*hostname = sockaddr->hostname = apr_pstrdup(sockaddr->pool, hptr->h_name);
return APR_SUCCESS;
}
*hostname = NULL;
-#if defined(WIN32)
+#if APR_HAS_THREADS && !defined(GETHOSTBYADDR_IS_THREAD_SAFE) && \
+ defined(HAVE_GETHOSTBYADDR_R) && !defined(BEOS) && \
+ !defined(GETHOSTBYNAME_R_HOSTENT_DATA)
+ return hosterror + APR_OS_START_SYSERR;
+#elif defined(WIN32)
return apr_get_netos_error();
#elif defined(OS2)
return h_errno;