From: Stefan Neis Date: Sun, 27 Nov 2005 17:46:39 +0000 (+0000) Subject: Detect thread-safe versions of gethostbyname/gethostbyaddr/getservbyname X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/bebf40d5a0c486ec4f524fa15a886c748c0e469a Detect thread-safe versions of gethostbyname/gethostbyaddr/getservbyname and how many arguments they use. Detect thread-safe versions of localtime/gmtime and readdir. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36267 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/aclocal.m4 b/aclocal.m4 index 67793d4d2c..b0f5341959 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -18,4 +18,6 @@ m4_include([build/aclocal/gtk-2.0.m4]) m4_include([build/aclocal/gtk.m4]) m4_include([build/aclocal/pkg.m4]) m4_include([build/aclocal/sdl.m4]) +m4_include([build/aclocal/ax_func_which_gethostbyname_r.m4]) +m4_include([build/aclocal/ac_raf_func_which_getservbyname_r.m4]) m4_include([acinclude.m4]) diff --git a/build/aclocal/ac_raf_func_which_getservbyname_r.m4 b/build/aclocal/ac_raf_func_which_getservbyname_r.m4 new file mode 100644 index 0000000000..2aef740d36 --- /dev/null +++ b/build/aclocal/ac_raf_func_which_getservbyname_r.m4 @@ -0,0 +1,75 @@ +dnl @synopsis AC_raf_FUNC_WHICH_GETSERVBYNAME_R +dnl +dnl Provides a test to determine the correct way to call +dnl getservbyname_r: +dnl +dnl - defines HAVE_FUNC_GETSERVBYNAME_R_6 if it needs 6 arguments (e.g linux) +dnl - defines HAVE_FUNC_GETSERVBYNAME_R_5 if it needs 5 arguments (e.g. solaris) +dnl - defines HAVE_FUNC_GETSERVBYNAME_R_4 if it needs 4 arguments (e.g. osf/1) +dnl +dnl An example use can be found at +dnl http://raf.org/autoconf/net_getservbyname.c +dnl +dnl Based on Caolan McNamara's gethostbyname_r macro. Based on David +dnl Arnold's autoconf suggestion in the threads faq. +dnl +dnl @category Misc +dnl @author raf +dnl @version 2001-08-20 +dnl @license GPLWithACException + +AC_DEFUN([AC_raf_FUNC_WHICH_GETSERVBYNAME_R], +[AC_CACHE_CHECK(for getservbyname_r, ac_cv_func_which_getservbyname_r, [ +AC_CHECK_FUNC(getservbyname_r, [ + AC_TRY_COMPILE([ +# include + ], [ + + char *name; + char *proto; + struct servent *se; + struct servent_data data; + (void) getservbyname_r(name, proto, se, &data); + + ],ac_cv_func_which_getservbyname_r=four, + [ + AC_TRY_COMPILE([ +# include + ], [ + char *name; + char *proto; + struct servent *se, *res; + char buffer[2048]; + int buflen = 2048; + (void) getservbyname_r(name, proto, se, buffer, buflen, &res) + ],ac_cv_func_which_getservbyname_r=six, + + [ + AC_TRY_COMPILE([ +# include + ], [ + char *name; + char *proto; + struct servent *se; + char buffer[2048]; + int buflen = 2048; + (void) getservbyname_r(name, proto, se, buffer, buflen) + ],ac_cv_func_which_getservbyname_r=five,ac_cv_func_which_getservbyname_r=no) + + ] + + ) + ] + )] + ,ac_cv_func_which_getservbyname_r=no)]) + +if test $ac_cv_func_which_getservbyname_r = six; then + AC_DEFINE(HAVE_FUNC_GETSERVBYNAME_R_6) +elif test $ac_cv_func_which_getservbyname_r = five; then + AC_DEFINE(HAVE_FUNC_GETSERVBYNAME_R_5) +elif test $ac_cv_func_which_getservbyname_r = four; then + AC_DEFINE(HAVE_FUNC_GETSERVBYNAME_R_4) + +fi + +]) diff --git a/build/aclocal/ax_func_which_gethostbyname_r.m4 b/build/aclocal/ax_func_which_gethostbyname_r.m4 new file mode 100644 index 0000000000..b71519edb6 --- /dev/null +++ b/build/aclocal/ax_func_which_gethostbyname_r.m4 @@ -0,0 +1,155 @@ +dnl @synopsis AX_FUNC_WHICH_GETHOSTBYNAME_R +dnl +dnl Determines which historical variant of the gethostbyname_r() call +dnl (taking three, five, or six arguments) is available on the system +dnl and defines one of the following macros accordingly: +dnl +dnl HAVE_FUNC_GETHOSTBYNAME_R_6 +dnl HAVE_FUNC_GETHOSTBYNAME_R_5 +dnl HAVE_FUNC_GETHOSTBYNAME_R_3 +dnl +dnl If used in conjunction with gethostname.c, the API demonstrated in +dnl test.c can be used regardless of which gethostbyname_r() is +dnl available. These example files can be found at +dnl http://www.csn.ul.ie/~caolan/publink/gethostbyname_r +dnl +dnl based on David Arnold's autoconf suggestion in the threads faq +dnl +dnl Originally named "AC_caolan_FUNC_WHICH_GETHOSTBYNAME_R". Rewritten +dnl for Autoconf 2.5x by Daniel Richard G. +dnl +dnl @category InstalledPackages +dnl @author Caolan McNamara +dnl @author Daniel Richard G. +dnl @version 2005-01-21 +dnl @license GPLWithACException + +AC_DEFUN([AX_FUNC_WHICH_GETHOSTBYNAME_R], [ + + AC_LANG_PUSH(C) + AC_MSG_CHECKING([how many arguments gethostbyname_r() takes]) + + AC_CACHE_VAL(ac_cv_func_which_gethostbyname_r, [ + +################################################################ + +ac_cv_func_which_gethostbyname_r=unknown + +# +# ONE ARGUMENT (sanity check) +# + +# This should fail, as there is no variant of gethostbyname_r() that takes +# a single argument. If it actually compiles, then we can assume that +# netdb.h is not declaring the function, and the compiler is thereby +# assuming an implicit prototype. In which case, we're out of luck. +# +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM( + [[#include ]], + [[ + char *name = "www.gnu.org"; + (void)gethostbyname_r(name) /* ; */ + ]]), + ac_cv_func_which_gethostbyname_r=no) + +# +# SIX ARGUMENTS +# (e.g. Linux) +# + +if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then + +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM( + [[#include ]], + [[ + char *name = "www.gnu.org"; + struct hostent ret, *retp; + char buf@<:@1024@:>@; + int buflen = 1024; + int my_h_errno; + (void)gethostbyname_r(name, &ret, buf, buflen, &retp, &my_h_errno) /* ; */ + ]]), + ac_cv_func_which_gethostbyname_r=six) + +fi + +# +# FIVE ARGUMENTS +# (e.g. Solaris) +# + +if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then + +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM( + [[#include ]], + [[ + char *name = "www.gnu.org"; + struct hostent ret; + char buf@<:@1024@:>@; + int buflen = 1024; + int my_h_errno; + (void)gethostbyname_r(name, &ret, buf, buflen, &my_h_errno) /* ; */ + ]]), + ac_cv_func_which_gethostbyname_r=five) + +fi + +# +# THREE ARGUMENTS +# (e.g. AIX, HP-UX, Tru64) +# + +if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then + +AC_COMPILE_IFELSE( + AC_LANG_PROGRAM( + [[#include ]], + [[ + char *name = "www.gnu.org"; + struct hostent ret; + struct hostent_data data; + (void)gethostbyname_r(name, &ret, &data) /* ; */ + ]]), + ac_cv_func_which_gethostbyname_r=three) + +fi + +################################################################ + +]) dnl end AC_CACHE_VAL + +case "$ac_cv_func_which_gethostbyname_r" in + three) + AC_MSG_RESULT([three]) + AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_3) + ;; + + five) + AC_MSG_RESULT([five]) + AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_5) + ;; + + six) + AC_MSG_RESULT([six]) + AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_6) + ;; + + no) + AC_MSG_RESULT([cannot find function declaration in netdb.h]) + ;; + + unknown) + AC_MSG_RESULT([can't tell]) + ;; + + *) + AC_MSG_ERROR([internal error]) + ;; +esac + +AC_LANG_POP(C) + +]) dnl end AC_DEFUN diff --git a/configure.in b/configure.in index ff87146c59..364b486c10 100644 --- a/configure.in +++ b/configure.in @@ -4969,6 +4969,52 @@ else fi fi +AC_CHECK_FUNC(localtime_r, [ AC_DEFINE(HAVE_LOCALTIME_R) ]) +AC_SUBST(HAVE_LOCALTIME_R) +AC_CHECK_FUNC(gmtime_r, [ AC_DEFINE(HAVE_GMTIME_R) ]) +AC_SUBST(HAVE_GMTIME_R) +AC_CHECK_FUNC(readdir_r, [ AC_DEFINE(HAVE_READDIR_R) ]) +AC_SUBST(HAVE_READDIR_R) +dnl By preference, use getaddrinfo which avoids thread safety issues. +dnl If that is not available, check for gethostbyname_r/gethostbyaddr_r +dnl and getservbyname_r +AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(HAVE_GETADDRINFO), + dnl no getaddrinfo, so check for gethostbyname_r and + dnl related functions (taken from python's configure.in) + dnl sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments + [ AX_FUNC_WHICH_GETHOSTBYNAME_R + if test "x$ac_cv_func_which_gethostbyname_r" = "xno" -o \ + "x$ac_cv_func_which_gethostbyname_r" = "xunknown" ; then + AC_CHECK_FUNC(gethostbyname, [ AC_DEFINE(HAVE_GETHOSTBYNAME) ]) + fi + AC_SUBST(HAVE_FUNC_GETHOSTBYNAME_R_6) + AC_SUBST(HAVE_FUNC_GETHOSTBYNAME_R_5) + AC_SUBST(HAVE_FUNC_GETHOSTBYNAME_R_3) + AC_SUBST(HAVE_GETHOSTBYNAME) + dnl A similar test for getservbyname_r + dnl I'm tempted to just not do this test which is taking much time and + dnl do something similar as for gethostbyaddr_r, but OTOH the macro + dnl doing the test already exists, so using it is easy enough. - SN + AC_raf_FUNC_WHICH_GETSERVBYNAME_R + if test "x$ac_cv_func_which_getservbyname_r" = "xno" -o \ + "x$ac_cv_func_which_getservbyname_r" = "xunknown" ; then + AC_CHECK_FUNCS(getservbyname,[ AC_DEFINE(HAVE_GETSERVBYNAME) ]) + fi + AC_SUBST(HAVE_FUNC_GETSERVBYNAME_R_6) + AC_SUBST(HAVE_FUNC_GETSERVBYNAME_R_5) + AC_SUBST(HAVE_FUNC_GETSERVBYNAME_R_4) + AC_SUBST(HAVE_GETSERVBYNAME) + dnl For gethostbyaddr_r, we currently do no separate test, instead, we + dnl silently assume it's available exactly if gethostbyname_r is + dnl available and always requires two more arguments than + dnl gethostbyname_r. + dnl (also, I'm lazy and there no m4 file that's ready for use for this + dnl function, although it should be easy to rewrite the gethostbyname_r + dnl check to fit this case, if it's really needed. - SN ) + ] +) + + if test "$wxUSE_THREADS" = "yes"; then AC_DEFINE(wxUSE_THREADS) diff --git a/setup.h.in b/setup.h.in index 06c81b9508..6619e61c00 100644 --- a/setup.h.in +++ b/setup.h.in @@ -865,15 +865,45 @@ /* Define if you have BSD flock() function. */ #undef HAVE_FLOCK +/* Define if you have a gethostbyname_r function taking 6 arguments. */ +#undef HAVE_FUNC_GETHOSTBYNAME_R_6 + +/* Define if you have a gethostbyname_r function taking 5 arguments. */ +#undef HAVE_FUNC_GETHOSTBYNAME_R_5 + +/* Define if you have a gethostbyname_r function taking 3 arguments. */ +#undef HAVE_FUNC_GETHOSTBYNAME_R_3 + +/* Define if you only have a gethostbyname function */ +#undef HAVE_GETHOSTBYNAME + /* Define if you have the gethostname function. */ #undef HAVE_GETHOSTNAME +/* Define if you have a getservbyname_r function taking 6 arguments. */ +#undef HAVE_FUNC_GETSERVBYNAME_R_6 + +/* Define if you have a getservbyname_r function taking 5 arguments. */ +#undef HAVE_FUNC_GETSERVBYNAME_R_5 + +/* Define if you have a getservbyname_r function taking 4 arguments. */ +#undef HAVE_FUNC_GETSERVBYNAME_R_4 + +/* Define if you only have a getservbyname function */ +#undef HAVE_GETSERVBYNAME + +/* Define if you have the gmtime_r function. */ +#undef HAVE_GMTIME_R + /* Define if you have the inet_addr function. */ #undef HAVE_INET_ADDR /* Define if you have the inet_aton function. */ #undef HAVE_INET_ATON +/* Define if you have the localtime_r function. */ +#undef HAVE_LOCALTIME_R + /* Define if you have the mktemp function. */ #undef HAVE_MKTEMP @@ -886,6 +916,9 @@ /* Define if you have the putenv function. */ #undef HAVE_PUTENV +/* Define if you have the readdir_r function. */ +#undef HAVE_READDIR_R + /* Define if you have the setenv function. */ #undef HAVE_SETENV