apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bo...@apache.org
Subject svn commit: r662607 - in /apr/apr/branches/1.3.x: build/apr_hints.m4 build/apr_network.m4 configure.in network_io/unix/sockaddr.c test/testsock.c
Date Tue, 03 Jun 2008 00:20:24 GMT
Author: bojan
Date: Mon Jun  2 17:20:24 2008
New Revision: 662607

URL: http://svn.apache.org/viewvc?rev=662607&view=rev
Log:
Backport rr661178 and 662326 from the trunk.
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().
Add test for apr_getservbyname().

Modified:
    apr/apr/branches/1.3.x/build/apr_hints.m4
    apr/apr/branches/1.3.x/build/apr_network.m4
    apr/apr/branches/1.3.x/configure.in
    apr/apr/branches/1.3.x/network_io/unix/sockaddr.c
    apr/apr/branches/1.3.x/test/testsock.c

Modified: apr/apr/branches/1.3.x/build/apr_hints.m4
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/build/apr_hints.m4?rev=662607&r1=662606&r2=662607&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/build/apr_hints.m4 (original)
+++ apr/apr/branches/1.3.x/build/apr_hints.m4 Mon Jun  2 17:20:24 2008
@@ -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])
@@ -419,6 +420,7 @@
         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])
         ;;
@@ -427,6 +429,7 @@
         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])

Modified: apr/apr/branches/1.3.x/build/apr_network.m4
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/build/apr_network.m4?rev=662607&r1=662606&r2=662607&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/build/apr_network.m4 (original)
+++ apr/apr/branches/1.3.x/build/apr_network.m4 Mon Jun  2 17:20:24 2008
@@ -282,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], [

Modified: apr/apr/branches/1.3.x/configure.in
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/configure.in?rev=662607&r1=662606&r2=662607&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/configure.in (original)
+++ apr/apr/branches/1.3.x/configure.in Mon Jun  2 17:20:24 2008
@@ -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

Modified: apr/apr/branches/1.3.x/network_io/unix/sockaddr.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/network_io/unix/sockaddr.c?rev=662607&r1=662606&r2=662607&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/network_io/unix/sockaddr.c (original)
+++ apr/apr/branches/1.3.x/network_io/unix/sockaddr.c Mon Jun  2 17:20:24 2008
@@ -705,17 +705,63 @@
 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;
 }
 

Modified: apr/apr/branches/1.3.x/test/testsock.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/test/testsock.c?rev=662607&r1=662606&r2=662607&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/test/testsock.c (original)
+++ apr/apr/branches/1.3.x/test/testsock.c Mon Jun  2 17:20:24 2008
@@ -73,6 +73,26 @@
     ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname);
 }
 
+static void test_serv_by_name(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+    apr_sockaddr_t *sa;
+
+    rv = apr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 0, 0, p);
+    APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
+
+    rv = apr_getservbyname(sa, "ftp");
+    APR_ASSERT_SUCCESS(tc, "Problem getting ftp service", rv);
+    ABTS_INT_EQUAL(tc, 21, sa->port);
+
+    rv = apr_getservbyname(sa, "complete_and_utter_rubbish");
+    APR_ASSERT_SUCCESS(tc, "Problem getting non-existent service", !rv);
+
+    rv = apr_getservbyname(sa, "http");
+    APR_ASSERT_SUCCESS(tc, "Problem getting http service", rv);
+    ABTS_INT_EQUAL(tc, 80, sa->port);
+}
+
 static apr_socket_t *setup_socket(abts_case *tc)
 {
     apr_status_t rv;
@@ -318,6 +338,7 @@
     suite = ADD_SUITE(suite)
 
     abts_run_test(suite, test_addr_info, NULL);
+    abts_run_test(suite, test_serv_by_name, NULL);
     abts_run_test(suite, test_create_bind_listen, NULL);
     abts_run_test(suite, test_send, NULL);
     abts_run_test(suite, test_recv, NULL);



Mime
View raw message