diff --git a/configure.ac b/configure.ac index fa260ad..40da1e7 100644 --- a/configure.ac +++ b/configure.ac @@ -38,34 +38,37 @@ AC_DEFUN([CONFIG_OPTION_MYSQL],[ [AC_MSG_ERROR([--with-mysql-source=PATH is required for standalone build])] ) - AC_MSG_CHECKING([mysql binary]) - MYSQL_BIN_VERSION= - ac_mysql_bin_dir= + ac_mysql_config= AC_ARG_WITH([mysql-bindir], - [AS_HELP_STRING([--with-mysql-bindir=PATH], [MySQL biarny directory PATH. This should be the directory where MySQL binary executables (i.e. mysql_config) are located])], + [AS_HELP_STRING([--with-mysql-bindir=PATH], [MySQL binary directory PATH. This should be the directory where mysql_config is located.])], [ - ac_mysql_bin_dir=`cd $withval && pwd` - if test ! -f "$ac_mysql_bin_dir/mysql_config" ; then - AC_MSG_ERROR([mysql_config not found! invalid MySQL base directory: $ac_mysql_bin_dir]) - fi + mysql_bin_dir=`cd $withval 2> /dev/null && pwd || echo ""` + ac_mysql_config="$mysql_bin_dir/mysql_config" + ], + [ + AC_PATH_PROG([ac_mysql_config], [mysql_config]) + ] + ) + + AC_MSG_CHECKING([mysql binary]) + if test ! -x "$ac_mysql_config" ; then + AC_MSG_ERROR([mysql_config not found! You have to specify the directory where mysql_config resides to --with-mysql-bindir=PATH.]) + fi - MYSQL_CFLAGS_ADD=`(cd $ac_mysql_bin_dir; ./mysql_config --cflags)` - MYSQL_CFLAGS="$MYSQL_CFLAGS $MYSQL_CFLAGS_ADD" - AC_SUBST(MYSQL_CFLAGS) + MYSQL_CFLAGS_ADD=`"$ac_mysql_config" --cflags` + MYSQL_CFLAGS="$MYSQL_CFLAGS $MYSQL_CFLAGS_ADD" + AC_SUBST(MYSQL_CFLAGS) - MYSQL_BIN_VERSION=`(cd $ac_mysql_bin_dir; ./mysql_config --version)` - AC_MSG_RESULT([yes: Using $ac_mysql_bin_dir, version $MYSQL_BIN_VERSION]) + MYSQL_BIN_VERSION=`"$ac_mysql_config" --version` + AC_MSG_RESULT([yes: Using $ac_mysql_config, version $MYSQL_BIN_VERSION]) - MYSQL_LIB=`(cd $ac_mysql_bin_dir; ./mysql_config --libs_r)` - LIB_DIR=`echo $MYSQL_LIB | sed -e "s|.* -L||" | sed -e "s| .*||"` - if test a`basename $LIB_DIR` = amysql ; then - MYSQL_LIB="-L`dirname $LIB_DIR` $MYSQL_LIB" - fi - AC_SUBST(MYSQL_LIB) - ], - [AC_MSG_ERROR([--with-mysql-bindir=PATH is required to build handlersocket plugin])] - ) + MYSQL_LIB=`"$ac_mysql_config" --libs_r` + LIB_DIR=`echo $MYSQL_LIB | sed -e "s|.* -L||" | sed -e "s| .*||"` + if test a`basename "$LIB_DIR"` = amysql ; then + MYSQL_LIB="-L`dirname $LIB_DIR` $MYSQL_LIB" + fi + AC_SUBST(MYSQL_LIB) if test a$MYSQL_SOURCE_VERSION != a$MYSQL_BIN_VERSION ; then AC_MSG_ERROR([MySQL source version does not match MySQL binary version]) @@ -86,9 +89,11 @@ AC_DEFUN([CONFIG_OPTION_MYSQL],[ fi ], [ - LIB_DIR_TMP1=`(cd $ac_mysql_bin_dir; ./mysql_config --libs_r)` - LIB_DIR_TMP2=`echo $LIB_DIR_TMP1 | sed -e "s|.* -L||" | sed -e "s| .*||"` - ac_mysql_plugin_dir=$LIB_DIR_TMP2/plugin + LIB_DIR_TMP=`"$ac_mysql_config" --plugindir` + if test ! -d "$LIB_DIR_TMP"; then + LIB_DIR_TMP=`"$ac_mysql_config" --libs_r | sed -e "s|.* -L||" | sed -e "s| .*||"`/plugin + fi + ac_mysql_plugin_dir=$LIB_DIR_TMP PLUGIN_DIR="$ac_mysql_plugin_dir" AC_SUBST(PLUGIN_DIR) AC_MSG_RESULT([--with-mysql-plugindir was not set. Using $ac_mysql_plugin_dir]) @@ -108,6 +113,43 @@ AC_SUBST(HANDLERSOCKET_SUBDIRS) CFLAGS="$CFLAGS -Werror" CXXFLAGS="$CXXFLAGS -Wall -g -fno-rtti -fno-exceptions -fPIC -DPIC" +AC_CHECK_FUNC([strerror_r], + [ + AC_LANG_PUSH([C++]) + AC_MSG_CHECKING([if strerror_r is POSIX-compliant]) + AC_TRY_COMPILE( + [ +#include + ], + [ +int t = strerror_r(0, (char *)0, 0) * 2; + ], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_POSIX_COMPLIANT_STRERROR_R], [1], [Define to 1 if libc has POSIX-compliant strerror_r()]) + ], + [AC_MSG_RESULT([no])] + ) + AC_MSG_CHECKING([if strerror_r is GNU-specific]) + AC_TRY_COMPILE( + [ +#include + ], + [ +char *t = 0; +t = strerror_r(0, t, 0); + ], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_GNU_SPECIFIC_STRERROR_R], [1], [Define to 1 if libc has GNU-compliant strerror_r()]) + ], + [AC_MSG_RESULT([no])] + ) + AC_LANG_POP + ] +) + + AC_CONFIG_FILES([Makefile handlersocket/Makefile libhsclient/Makefile diff --git a/libhsclient/string_util.cpp b/libhsclient/string_util.cpp index 3d7ae63..555e0ab 100644 --- a/libhsclient/string_util.cpp +++ b/libhsclient/string_util.cpp @@ -6,8 +6,14 @@ * See COPYRIGHT.txt for details. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include +#include +#include #include "string_util.hpp" @@ -57,20 +63,52 @@ append_uint32(string_buffer& buf, uint32_t v) } } +std::string +to_stdstring(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + + std::string buf; + buf.resize(64); + const std::size_t required = vsnprintf(&buf[0], buf.capacity(), format, ap); + if (required > buf.size()) { + buf.resize(required); + vsnprintf(&buf[0], buf.size(), format, ap); + } else { + buf.resize(required); + } + va_end(ap); + return buf; +} + std::string to_stdstring(uint32_t v) { - char buf[64]; - snprintf(buf, sizeof(buf), "%lu", static_cast(v)); - return std::string(buf); + return to_stdstring("%lu", static_cast(v)); } int errno_string(const char *s, int en, std::string& err_r) { - char buf[64]; - snprintf(buf, sizeof(buf), "%s: %d", s, en); - err_r = std::string(buf); +#if defined(HAVE_POSIX_COMPLIANT_STRERROR_R) + char buf[512]; + if (!strerror_r(en, buf, sizeof(buf))) { + std::string tmp(to_stdstring("%s: %s", s, buf)); + err_r.swap(tmp); + return en; + } +#elif defined(HAVE_GNU_SPECIFIC_STRERROR_R) + char buf[512]; + char *p = strerror_r(en, buf, sizeof(buf)); + if (p) { + std::string tmp(to_stdstring("%s: %s", s, p)); + err_r.swap(tmp); + return en; + } +#endif + std::string tmp(to_stdstring("%s: %d", s, en)); + err_r.swap(tmp); return en; } diff --git a/libhsclient/string_util.hpp b/libhsclient/string_util.hpp index 4599480..76ac33d 100644 --- a/libhsclient/string_util.hpp +++ b/libhsclient/string_util.hpp @@ -32,6 +32,7 @@ memchr_char(char *s, int c, size_t n) string_wref get_token(char *& wp, char *wp_end, char delim); uint32_t atoi_uint32_nocheck(const char *start, const char *finish); +std::string to_stdstring(const char *format, ...); std::string to_stdstring(uint32_t v); void append_uint32(string_buffer& buf, uint32_t v);