diff options
author | jerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68> | 2001-07-31 02:10:11 +0000 |
---|---|---|
committer | jerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68> | 2001-07-31 02:10:11 +0000 |
commit | 691d2acacdb354089057eb195001a0e27f1afb4c (patch) | |
tree | e7cdf474470603a01b7b04aa49e0cc653f52db1b | |
parent | dd23d6460537c44d641d821fa1a633c23b45911c (diff) | |
download | libapr-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-- | CHANGES | 4 | ||||
-rw-r--r-- | acconfig.h | 1 | ||||
-rw-r--r-- | build/apr_network.m4 | 63 | ||||
-rw-r--r-- | configure.in | 9 | ||||
-rw-r--r-- | network_io/unix/sa_common.c | 60 |
5 files changed, 131 insertions, 6 deletions
@@ -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; |