On Wed, 2008-05-28 at 11:20 +1000, Bojan Smojver wrote:
> For instance, something like the attached.
Don't you just hate it when you have to do this?
--
Bojan
Index: network_io/unix/sockaddr.c
===================================================================
--- network_io/unix/sockaddr.c (revision 660759)
+++ network_io/unix/sockaddr.c (working copy)
@@ -705,17 +705,62 @@
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) {
+ 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_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;
}
Index: configure.in
===================================================================
--- configure.in (revision 660759)
+++ configure.in (working copy)
@@ -684,6 +684,7 @@
ac_cv_define_READDIR_IS_THREAD_SAFE=no
ac_cv_define_GETHOSTBYNAME_IS_THREAD_SAFE=no
ac_cv_define_GETHOSTBYADDR_IS_THREAD_SAFE=no
+ac_cv_define_GETSERVBYNAME_IS_THREAD_SAFE=no
if test "$threads" = "1"; then
echo "APR will use threads"
AC_CHECK_LIB(c_r, readdir,
@@ -703,7 +704,14 @@
AC_DEFINE(GETHOSTBYADDR_IS_THREAD_SAFE, 1,
[Define if gethostbyaddr is thread safe])
fi
- AC_CHECK_FUNCS(gethostbyname_r gethostbyaddr_r)
+ if test "x$apr_getservbyname_is_thread_safe" = "x"; then
+ AC_CHECK_LIB(c_r, getservbyname, apr_getservbyname_is_thread_safe=yes)
+ fi
+ if test "$apr_getservbyname_is_thread_safe" = "yes"; then
+ AC_DEFINE(GETSERVBYNAME_IS_THREAD_SAFE, 1,
+ [Define if getservbyname is thread safe])
+ fi
+ AC_CHECK_FUNCS(gethostbyname_r gethostbyaddr_r getservbyname_r)
else
echo "APR will be non-threaded"
fi
@@ -2131,6 +2139,11 @@
APR_CHECK_GETHOSTBYNAME_R_STYLE
fi
+# Check the types only if we have getservbyname_r
+if test "$ac_cv_func_getservbyname_r" = "yes"; then
+ APR_CHECK_GETSERVBYNAME_R_STYLE
+fi
+
APR_CHECK_TCP_NODELAY_INHERITED
APR_CHECK_O_NONBLOCK_INHERITED
APR_CHECK_TCP_NODELAY_WITH_CORK
Index: build/apr_hints.m4
===================================================================
--- build/apr_hints.m4 (revision 660759)
+++ build/apr_hints.m4 (working copy)
@@ -97,6 +97,7 @@
APR_SETVAR(SHELL, [sh])
APR_SETIFNULL(apr_gethostbyname_is_thread_safe, [yes])
APR_SETIFNULL(apr_gethostbyaddr_is_thread_safe, [yes])
+ APR_SETIFNULL(apr_getservbyname_is_thread_safe, [yes])
;;
*-hi-hiux)
APR_ADDTO(CPPFLAGS, [-DHIUX])
@@ -415,19 +416,21 @@
APR_ADDTO(CPPFLAGS, [-D_TANDEM_SOURCE -D_XOPEN_SOURCE_EXTENDED=1])
;;
*-ibm-os390)
- APR_SETIFNULL(apr_lock_method, [USE_SYSVSEM_SERIALIZE])
- APR_SETIFNULL(apr_sysvsem_is_global, [yes])
- APR_SETIFNULL(apr_gethostbyname_is_thread_safe, [yes])
- APR_SETIFNULL(apr_gethostbyaddr_is_thread_safe, [yes])
- AC_DEFINE(HAVE_ZOS_PTHREADS, 1, [Define for z/OS pthread API nuances])
- APR_ADDTO(CPPFLAGS, [-U_NO_PROTO -DSIGPROCMASK_SETS_THREAD_MASK -DTCP_NODELAY=1])
- ;;
+ APR_SETIFNULL(apr_lock_method, [USE_SYSVSEM_SERIALIZE])
+ APR_SETIFNULL(apr_sysvsem_is_global, [yes])
+ APR_SETIFNULL(apr_gethostbyname_is_thread_safe, [yes])
+ APR_SETIFNULL(apr_gethostbyaddr_is_thread_safe, [yes])
+ APR_SETIFNULL(apr_getservbyname_is_thread_safe, [yes])
+ AC_DEFINE(HAVE_ZOS_PTHREADS, 1, [Define for z/OS pthread API nuances])
+ APR_ADDTO(CPPFLAGS, [-U_NO_PROTO -DSIGPROCMASK_SETS_THREAD_MASK -DTCP_NODELAY=1])
+ ;;
*-ibm-as400)
- APR_SETIFNULL(apr_lock_method, [USE_SYSVSEM_SERIALIZE])
- APR_SETIFNULL(apr_process_lock_is_global, [yes])
- APR_SETIFNULL(apr_gethostbyname_is_thread_safe, [yes])
- APR_SETIFNULL(apr_gethostbyaddr_is_thread_safe, [yes])
- ;;
+ APR_SETIFNULL(apr_lock_method, [USE_SYSVSEM_SERIALIZE])
+ APR_SETIFNULL(apr_process_lock_is_global, [yes])
+ APR_SETIFNULL(apr_gethostbyname_is_thread_safe, [yes])
+ APR_SETIFNULL(apr_gethostbyaddr_is_thread_safe, [yes])
+ APR_SETIFNULL(apr_getservbyname_is_thread_safe, [yes])
+ ;;
*cygwin*)
APR_ADDTO(CPPFLAGS, [-DCYGWIN])
;;
Index: build/apr_network.m4
===================================================================
--- build/apr_network.m4 (revision 660759)
+++ build/apr_network.m4 (working copy)
@@ -244,6 +244,8 @@
],[
int tmp = gethostbyname_r((const char *) 0, (struct hostent *) 0,
(char *) 0, 0, (struct hostent **) 0, &tmp);
+/* use tmp to suppress the warning */
+tmp=0;
], ac_cv_gethostbyname_r_style=glibc2, ac_cv_gethostbyname_r_style=none))
if test "$ac_cv_gethostbyname_r_style" = "glibc2"; then
@@ -269,8 +271,10 @@
#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))
+ (struct hostent_data *) 0);
+/* use tmp to suppress the warning */
+tmp=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])
@@ -278,6 +282,103 @@
])
dnl
+dnl Checks the definition of getservbyname_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_GETSERVBYNAME_R_STYLE], [
+
+dnl Try and compile a glibc2 getservbyname_r piece of code, and set the
+dnl style of the routines to glibc2 on success
+AC_CACHE_CHECK([style of getservbyname_r routine], ac_cv_getservbyname_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 = getservbyname_r((const char *) 0, (const char *) 0,
+ (struct servent *) 0, (char *) 0, 0,
+ (struct servent **) 0);
+/* use tmp to suppress the warning */
+tmp=0;
+], ac_cv_getservbyname_r_style=glibc2, [
+
+dnl Try and compile a Solaris getservbyname_r piece of code, and set the
+dnl style of the routines to solaris on success
+AC_CACHE_VAL(ac_cv_getservbyname_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
+],[
+struct servent tmp = getservbyname_r((const char *) 0, (const char *) 0,
+ (struct servent *) 0, (char *) 0, 0);
+/* use tmp to suppress the warning */
+tmp=NULL;
+], ac_cv_getservbyname_r_style=solaris, [
+
+dnl Try and compile a OSF/1 getservbyname_r piece of code, and set the
+dnl style of the routines to osf1 on success
+AC_CACHE_VAL( ac_cv_getservbyname_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 = getservbyname_r((const char *) 0, (const char *) 0,
+ (struct servent *) 0, (struct servent_data *) 0);
+/* use tmp to suppress the warning */
+tmp=0;
+], ac_cv_getservbyname_r_style=osf1, ac_cv_getservbyname_r_style=none))]))]))
+
+if test "$ac_cv_getservbyname_r_style" = "glibc2"; then
+ AC_DEFINE(GETSERVBYNAME_R_GLIBC2, 1, [Define if getservbyname_r has the glibc style])
+elif test "$ac_cv_getservbyname_r_style" = "solaris"; then
+ AC_DEFINE(GETSERVBYNAME_R_SOLARIS, 1, [Define if getservbyname_r has the Solaris style])
+elif test "$ac_cv_getservbyname_r_style" = "osf1"; then
+ AC_DEFINE(GETSERVBYNAME_R_OSF1, 1, [Define if getservbyname_r has the OSF/1 style])
+fi
+])
+
+dnl
dnl see if TCP_NODELAY setting is inherited from listening sockets
dnl
AC_DEFUN([APR_CHECK_TCP_NODELAY_INHERITED], [