From 7f41877b413bb1420bb013d45cbbca7b5ab4b99e Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Mon, 1 Feb 2010 13:27:23 +0000 Subject: [PATCH] memcmp portability. git-svn-id: file:///svn/unbound/trunk@1972 be551aaa-1e26-0410-a405-d3ace91eadb9 --- acx_nlnetlabs.m4 | 39 +++++++++++++++++++++- compat/memcmp.c | 25 ++++++++++++++ config.h.in | 12 +++++++ configure | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 ++ doc/Changelog | 1 + 6 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 compat/memcmp.c diff --git a/acx_nlnetlabs.m4 b/acx_nlnetlabs.m4 index 2d1292257..dc07f66e1 100644 --- a/acx_nlnetlabs.m4 +++ b/acx_nlnetlabs.m4 @@ -2,7 +2,8 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 5 +# Version 6 +# 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN # 2010-01-20 added AHX_COONFIG_STRLCAT # 2009-07-14 U_CHAR detection improved for windows crosscompile. # added ACX_FUNC_MALLOC @@ -68,6 +69,8 @@ # AHX_CONFIG_FLAG_OMITTED - define omitted flag # AHX_CONFIG_FLAG_EXT - define omitted extension flag # AHX_CONFIG_EXT_FLAGS - define the stripped extension flags +# ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters. +# AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED. # dnl Escape backslashes as \\, for C:\ paths, for the C preprocessor defines. @@ -1215,4 +1218,38 @@ AHX_CONFIG_FLAG_EXT(-D_ALL_SOURCE) AHX_CONFIG_FLAG_EXT(-D_LARGEFILE_SOURCE=1) ]) +dnl check if memcmp is using signed characters and replace if so. +AC_DEFUN([ACX_CHECK_MEMCMP_SIGNED], +[AC_MSG_CHECKING([if memcmp compares unsigned]) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include +int main(void) +{ + char a = 255, b = 0; + if(memcmp(&a, &b, 1) < 0) + return 1; + return 0; +} +]])], [AC_MSG_RESULT([yes]) ], +[ AC_MSG_RESULT([no]) + AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) + AC_LIBOBJ([memcmp]) +], [ AC_MSG_RESULT([cross-compile no]) + AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) + AC_LIBOBJ([memcmp]) +]) ]) + +dnl define memcmp to its replacement, pass unique id for program as arg +AC_DEFUN([AHX_MEMCMP_BROKEN], [ +#ifdef MEMCMP_IS_BROKEN +# ifdef memcmp +# undef memcmp +# endif +#define memcmp memcmp_$1 +int memcmp(const void *x, const void *y, size_t n); +#endif +]) + dnl End of file diff --git a/compat/memcmp.c b/compat/memcmp.c new file mode 100644 index 000000000..9446276f4 --- /dev/null +++ b/compat/memcmp.c @@ -0,0 +1,25 @@ +/* + * memcmp.c: memcmp compat implementation. + * + * Copyright (c) 2010, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. +*/ + +#include + +int memcmp(const void *x, const void *y, size_t n); + +int memcmp(const void *x, const void *y, size_t n) +{ + const uint8_t* x8 = (const uint8_t*)x; + const uint8_t* y8 = (const uint8_t*)y; + size_t i; + for(i=0; i y8[i]) + return 1; + } + return 0; +} diff --git a/config.h.in b/config.h.in index bd4e693a3..200fa3861 100644 --- a/config.h.in +++ b/config.h.in @@ -343,6 +343,9 @@ /* Define to the maximum message length to pass to syslog. */ #undef MAXSYSLOGMSGLEN +/* Define if memcmp() does not compare unsigned bytes */ +#undef MEMCMP_IS_BROKEN + /* Define if mkdir has one argument. */ #undef MKDIR_HAS_ONE_ARG @@ -774,6 +777,15 @@ struct tm *gmtime_r(const time_t *timep, struct tm *result); #endif /* IPV6_MIN_MTU */ +#ifdef MEMCMP_IS_BROKEN +# ifdef memcmp +# undef memcmp +# endif +#define memcmp memcmp_unbound +int memcmp(const void *x, const void *y, size_t n); +#endif + + #ifndef HAVE_CTIME_R #define ctime_r unbound_ctime_r diff --git a/configure b/configure index b50e4c1f4..7289e848d 100755 --- a/configure +++ b/configure @@ -21680,6 +21680,93 @@ rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: checking if memcmp compares unsigned" >&5 +$as_echo_n "checking if memcmp compares unsigned... " >&6; } +if test "$cross_compiling" = yes; then + { $as_echo "$as_me:$LINENO: result: cross-compile no" >&5 +$as_echo "cross-compile no" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define MEMCMP_IS_BROKEN 1 +_ACEOF + + case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +int main(void) +{ + char a = 255, b = 0; + if(memcmp(&a, &b, 1) < 0) + return 1; + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define MEMCMP_IS_BROKEN 1 +_ACEOF + + case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + for ac_func in inet_aton do diff --git a/configure.ac b/configure.ac index 33b43f9f0..0be409eaa 100644 --- a/configure.ac +++ b/configure.ac @@ -559,6 +559,7 @@ fi ACX_CHECK_NONBLOCKING_BROKEN ACX_MKDIR_ONE_ARG ACX_FUNC_IOCTLSOCKET +ACX_CHECK_MEMCMP_SIGNED AC_REPLACE_FUNCS(inet_aton) AC_REPLACE_FUNCS(inet_pton) AC_REPLACE_FUNCS(inet_ntop) @@ -719,6 +720,7 @@ AHX_CONFIG_W32_RANDOM AHX_CONFIG_W32_SRANDOM AHX_CONFIG_W32_FD_SET_T AHX_CONFIG_IPV6_MIN_MTU +AHX_MEMCMP_BROKEN(unbound) [ #ifndef HAVE_CTIME_R diff --git a/doc/Changelog b/doc/Changelog index ea5f7b0c7..d8fe7822f 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,5 +1,6 @@ 1 February 2010: Wouter - iana portlist updated. + - configure test for memcmp portability. 27 January 2010: Wouter - removed warning on format string in validator error log statement. -- 2.47.2