diff options
author | Yang Tse <yangsita@gmail.com> | 2008-09-12 01:16:26 +0000 |
---|---|---|
committer | Yang Tse <yangsita@gmail.com> | 2008-09-12 01:16:26 +0000 |
commit | b93ad10fa518cf49bcffaa55eb00df97310e8734 (patch) | |
tree | 5148687fc386a0b4fc0f818db2efd34761cb2376 | |
parent | 28e2007767054351a914941ab09374bfa7dfa381 (diff) |
improve detection of fdopen() and strerror_r()
-rw-r--r-- | acinclude.m4 | 109 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | m4/curl-functions.m4 | 331 |
3 files changed, 334 insertions, 112 deletions
diff --git a/acinclude.m4 b/acinclude.m4 index a12784285..4d42be49e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2620,115 +2620,6 @@ AC_DEFUN([CURL_CHECK_LOCALTIME_R], AC_MSG_RESULT(no))])]) ]) -dnl -dnl This function checks for strerror_r(). If it isn't found at first, it -dnl retries with _THREAD_SAFE defined, as that is what AIX seems to require -dnl in order to find this function. -dnl -dnl If the function is found, it will then proceed to check how the function -dnl actually works: glibc-style or POSIX-style. -dnl -dnl glibc: -dnl char *strerror_r(int errnum, char *buf, size_t n); -dnl -dnl What this one does is to return the error string (no surprises there), -dnl but it doesn't usually copy anything into buf! The 'buf' and 'n' -dnl parameters are only meant as an optional working area, in case strerror_r -dnl needs it. A quick test on a few systems shows that it's generally not -dnl touched at all. -dnl -dnl POSIX: -dnl int strerror_r(int errnum, char *buf, size_t n); -dnl -AC_DEFUN([CURL_CHECK_STRERROR_R], -[ - AC_CHECK_FUNCS(strerror_r) - - if test "x$ac_cv_func_strerror_r" = "xyes"; then - - AC_MSG_CHECKING(whether strerror_r is declared) - AC_EGREP_CPP(strerror_r,[ -#undef _REENTRANT -#include <string.h>],[ - AC_MSG_RESULT(yes)],[ - AC_MSG_RESULT(no) - AC_MSG_CHECKING(whether strerror_r with -D_REENTRANT is declared) - AC_EGREP_CPP(strerror_r,[ -#undef _REENTRANT -#define _REENTRANT -#include <string.h>],[ - AC_MSG_RESULT(yes)], - AC_MSG_RESULT(no) - AC_DEFINE(HAVE_NO_STRERROR_R_DECL, 1, [we have no strerror_r() proto]) - ) dnl with _THREAD_SAFE - ]) dnl plain cpp for it - - dnl determine if this strerror_r() is glibc or POSIX - AC_MSG_CHECKING([for a glibc strerror_r API]) - AC_TRY_RUN([ -#include <string.h> -#include <errno.h> -int -main () { - char buffer[1024]; /* big enough to play with */ - char *string = - strerror_r(EACCES, buffer, sizeof(buffer)); - /* this should've returned a string */ - if(!string || !string[0]) - return 99; - return 0; -} -], - GLIBC_STRERROR_R="1" - AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()]) - AC_MSG_RESULT([yes]), - AC_MSG_RESULT([no]), - - dnl Use an inferior method of strerror_r detection while cross-compiling - AC_EGREP_CPP(yes, [ -#include <features.h> -#ifdef __GLIBC__ -yes -#endif -], - dnl looks like glibc, so assume a glibc-style strerror_r() - GLIBC_STRERROR_R="1" - AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()]) - AC_MSG_RESULT([yes]), - AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!]) - ) dnl while cross-compiling - ) - - if test -z "$GLIBC_STRERROR_R"; then - - AC_MSG_CHECKING([for a POSIX strerror_r API]) - AC_TRY_RUN([ -#include <string.h> -#include <errno.h> -int -main () { - char buffer[1024]; /* big enough to play with */ - int error = - strerror_r(EACCES, buffer, sizeof(buffer)); - /* This should've returned zero, and written an error string in the - buffer.*/ - if(!buffer[0] || error) - return 99; - return 0; -} -], - AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()]) - AC_MSG_RESULT([yes]), - AC_MSG_RESULT([no]) , - dnl cross-compiling! - AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually!]) - ) - - fi dnl if not using glibc API - - fi dnl we have a strerror_r - -]) AC_DEFUN([CURL_CHECK_INET_NTOA_R], [ diff --git a/configure.ac b/configure.ac index d8d8b0c1f..264d1a43d 100644 --- a/configure.ac +++ b/configure.ac @@ -1855,7 +1855,7 @@ else CURL_CHECK_LOCALTIME_R() dnl is there a strerror_r() - CURL_CHECK_STRERROR_R() + dnl the old strerror_r check was done here checkfor_gmtime_r="yes" fi @@ -1876,7 +1876,7 @@ if test "x$RECENTAIX" = "xyes"; then CURL_CHECK_LOCALTIME_R() dnl is there a strerror_r() - CURL_CHECK_STRERROR_R() + dnl the old strerror_r check was done here checkfor_gmtime_r="yes" fi @@ -2034,10 +2034,12 @@ CURL_CHECK_FUNC_RECVFROM CURL_CHECK_FUNC_SEND CURL_CHECK_MSG_NOSIGNAL +CURL_CHECK_FUNC_FDOPEN CURL_CHECK_FUNC_FTRUNCATE CURL_CHECK_FUNC_GMTIME_R CURL_CHECK_FUNC_SIGACTION CURL_CHECK_FUNC_STRDUP +CURL_CHECK_FUNC_STRERROR_R CURL_CHECK_FUNC_STRTOK_R CURL_CHECK_FUNC_STRTOLL diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4 index 8973e968e..e05e70ee3 100644 --- a/m4/curl-functions.m4 +++ b/m4/curl-functions.m4 @@ -22,7 +22,7 @@ #*************************************************************************** # File version for 'aclocal' use. Keep it a single number. -# serial 1 +# serial 5 dnl CURL_INCLUDES_SIGNAL @@ -46,6 +46,27 @@ curl_includes_signal="\ ]) +dnl CURL_INCLUDES_STDIO +dnl ------------------------------------------------- +dnl Set up variable with list of headers that must be +dnl included when stdio.h is to be included. + +AC_DEFUN([CURL_INCLUDES_STDIO], [ +curl_includes_stdio="\ +/* includes start */ +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_STDIO_H +# include <stdio.h> +#endif +/* includes end */" + AC_CHECK_HEADERS( + sys/types.h stdio.h, + [], [], [$curl_includes_stdio]) +]) + + dnl CURL_INCLUDES_STDLIB dnl ------------------------------------------------- dnl Set up variable with list of headers that must be @@ -138,6 +159,91 @@ curl_includes_unistd="\ ]) +dnl CURL_CHECK_FUNC_FDOPEN +dnl ------------------------------------------------- +dnl Verify if fdopen is available, prototyped, and +dnl can be compiled. If all of these are true, and +dnl usage has not been previously disallowed with +dnl shell variable curl_disallow_fdopen, then +dnl HAVE_FDOPEN will be defined. + +AC_DEFUN([CURL_CHECK_FUNC_FDOPEN], [ + AC_REQUIRE([CURL_INCLUDES_STDIO])dnl + # + tst_links_fdopen="unknown" + tst_proto_fdopen="unknown" + tst_compi_fdopen="unknown" + tst_allow_fdopen="unknown" + # + AC_MSG_CHECKING([if fdopen can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([fdopen]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_fdopen="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_fdopen="no" + ]) + # + if test "$tst_links_fdopen" = "yes"; then + AC_MSG_CHECKING([if fdopen is prototyped]) + AC_EGREP_CPP([fdopen],[ + $curl_includes_stdio + ],[ + AC_MSG_RESULT([yes]) + tst_proto_fdopen="yes" + ],[ + AC_MSG_RESULT([no]) + tst_proto_fdopen="no" + ]) + fi + # + if test "$tst_proto_fdopen" = "yes"; then + AC_MSG_CHECKING([if fdopen is compilable]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_stdio + ]],[[ + if(0 != fdopen(0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_fdopen="yes" + ],[ + AC_MSG_RESULT([no]) + tst_compi_fdopen="no" + ]) + fi + # + if test "$tst_compi_fdopen" = "yes"; then + AC_MSG_CHECKING([if fdopen usage allowed]) + if test "x$curl_disallow_fdopen" != "xyes"; then + AC_MSG_RESULT([yes]) + tst_allow_fdopen="yes" + else + AC_MSG_RESULT([no]) + tst_allow_fdopen="no" + fi + fi + # + AC_MSG_CHECKING([if fdopen might be used]) + if test "$tst_links_fdopen" = "yes" && + test "$tst_proto_fdopen" = "yes" && + test "$tst_compi_fdopen" = "yes" && + test "$tst_allow_fdopen" = "yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_FDOPEN, 1, + [Define to 1 if you have the fdopen function.]) + ac_cv_func_fdopen="yes" + else + AC_MSG_RESULT([no]) + ac_cv_func_fdopen="no" + fi +]) + + dnl CURL_CHECK_FUNC_FTRUNCATE dnl ------------------------------------------------- dnl Verify if ftruncate is available, prototyped, and @@ -507,6 +613,229 @@ AC_DEFUN([CURL_CHECK_FUNC_STRDUP], [ ]) +dnl CURL_CHECK_FUNC_STRERROR_R +dnl ------------------------------------------------- +dnl Verify if strerror_r is available, prototyped, can be compiled and +dnl seems to work. If all of these are true, and usage has not been +dnl previously disallowed with shell variable curl_disallow_strerror_r, +dnl then HAVE_GLIBC_STRERROR_R or HAVE_POSIX_STRERROR_R will be defined. +dnl +dnl glibc-style strerror_r: +dnl +dnl char *strerror_r(int errnum, char *workbuf, size_t bufsize); +dnl +dnl glibc-style strerror_r returns a pointer to the the error string, +dnl and might use the provided workbuf as a scratch area if needed. A +dnl quick test on a few systems shows that it's usually not used at all. +dnl +dnl POSIX-style strerror_r: +dnl +dnl int strerror_r(int errnum, char *resultbuf, size_t bufsize); +dnl +dnl POSIX-style strerror_r returns 0 upon successful completion and the +dnl error string in the provided resultbuf. +dnl + +AC_DEFUN([CURL_CHECK_FUNC_STRERROR_R], [ + AC_REQUIRE([CURL_INCLUDES_STRING])dnl + # + tst_links_strerror_r="unknown" + tst_proto_strerror_r="unknown" + tst_compi_strerror_r="unknown" + tst_glibc_strerror_r="unknown" + tst_posix_strerror_r="unknown" + tst_allow_strerror_r="unknown" + tst_works_glibc_strerror_r="unknown" + tst_works_posix_strerror_r="unknown" + # + AC_MSG_CHECKING([if strerror_r can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([strerror_r]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_strerror_r="no" + ]) + # + if test "$tst_links_strerror_r" = "yes"; then + AC_MSG_CHECKING([if strerror_r is prototyped]) + AC_EGREP_CPP([strerror_r],[ + $curl_includes_string + ],[ + AC_MSG_RESULT([yes]) + tst_proto_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_proto_strerror_r="no" + ]) + fi + # + if test "$tst_proto_strerror_r" = "yes"; then + AC_MSG_CHECKING([if strerror_r is compilable]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_string + ]],[[ + if(0 != strerror_r(0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_compi_strerror_r="no" + ]) + fi + # + if test "$tst_compi_strerror_r" = "yes"; then + AC_MSG_CHECKING([if strerror_r is glibc like]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_string + ]],[[ + char *strerror_r(int errnum, char *workbuf, size_t bufsize); + if(0 != strerror_r(0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_glibc_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_glibc_strerror_r="no" + ]) + fi + # + dnl only do runtime verification when not cross-compiling + if test "x$cross_compiling" != "xyes" && + test "$tst_glibc_strerror_r" = "yes"; then + AC_MSG_CHECKING([if strerror_r seems to work]) + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_string +# include <errno.h> + ]],[[ + char buffer[1024]; + char *string = 0; + buffer[0] = '\0'; + string = strerror_r(EACCES, buffer, sizeof(buffer)); + if(!string) + exit(1); /* fail */ + if(!string[0]) + exit(1); /* fail */ + else + exit(0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_works_glibc_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_works_glibc_strerror_r="no" + ]) + fi + # + if test "$tst_compi_strerror_r" = "yes" && + test "$tst_works_glibc_strerror_r" != "yes"; then + AC_MSG_CHECKING([if strerror_r is POSIX like]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_string + ]],[[ + int strerror_r(int errnum, char *resultbuf, size_t bufsize); + if(0 != strerror_r(0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_posix_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_posix_strerror_r="no" + ]) + fi + # + dnl only do runtime verification when not cross-compiling + if test "x$cross_compiling" != "xyes" && + test "$tst_posix_strerror_r" = "yes"; then + AC_MSG_CHECKING([if strerror_r seems to work]) + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_string +# include <errno.h> + ]],[[ + char buffer[1024]; + int error = 1; + buffer[0] = '\0'; + error = strerror_r(EACCES, buffer, sizeof(buffer)); + if(error) + exit(1); /* fail */ + if(buffer[0] == '\0') + exit(1); /* fail */ + else + exit(0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_works_posix_strerror_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_works_posix_strerror_r="no" + ]) + fi + # + if test "$tst_glibc_strerror_r" = "yes" && + test "$tst_works_glibc_strerror_r" != "no" && + test "$tst_posix_strerror_r" != "yes"; then + tst_allow_strerror_r="check" + fi + if test "$tst_posix_strerror_r" = "yes" && + test "$tst_works_posix_strerror_r" != "no" && + test "$tst_glibc_strerror_r" != "yes"; then + tst_allow_strerror_r="check" + fi + if test "$tst_allow_strerror_r" = "check"; then + AC_MSG_CHECKING([if strerror_r usage allowed]) + if test "x$curl_disallow_strerror_r" != "xyes"; then + AC_MSG_RESULT([yes]) + tst_allow_strerror_r="yes" + else + AC_MSG_RESULT([no]) + tst_allow_strerror_r="no" + fi + fi + # + AC_MSG_CHECKING([if strerror_r might be used]) + if test "$tst_links_strerror_r" = "yes" && + test "$tst_proto_strerror_r" = "yes" && + test "$tst_compi_strerror_r" = "yes" && + test "$tst_allow_strerror_r" = "yes"; then + AC_MSG_RESULT([yes]) + if test "$tst_glibc_strerror_r" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_GLIBC_STRERROR_R, 1, + [Define to 1 if you have a working glibc-style strerror_r function.]) + fi + if test "$tst_posix_strerror_r" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_POSIX_STRERROR_R, 1, + [Define to 1 if you have a working POSIX-style strerror_r function.]) + fi + ac_cv_func_strerror_r="yes" + else + AC_MSG_RESULT([no]) + ac_cv_func_strerror_r="no" + fi + # + if test "$tst_compi_strerror_r" = "yes" && + test "$tst_allow_strerror_r" = "unknown"; then + AC_MSG_NOTICE([cannot determine strerror_r() style: edit lib/config.h manually.]) + fi + # +]) + + dnl CURL_CHECK_FUNC_STRTOK_R dnl ------------------------------------------------- dnl Verify if strtok_r is available, prototyped, and |