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], [

Reply via email to