From: Tobias Brunner Date: Tue, 25 Feb 2014 11:45:38 +0000 (+0100) Subject: utils: Add memrchr(3) replacement for platforms that don't support it X-Git-Tag: 5.1.2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ed241aeb3329f661bb3898ed8d5d579bedd3b8f;p=thirdparty%2Fstrongswan.git utils: Add memrchr(3) replacement for platforms that don't support it For instance, on Mac OS X memrchr(3) is not provided by the C library. --- diff --git a/configure.ac b/configure.ac index a881b079b8..ea6b5ed295 100644 --- a/configure.ac +++ b/configure.ac @@ -533,7 +533,7 @@ AC_CHECK_FUNC( ) AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r getpwuid_r) -AC_CHECK_FUNCS(fmemopen funopen mmap) +AC_CHECK_FUNCS(fmemopen funopen mmap memrchr) AC_CHECK_HEADERS(sys/sockio.h glob.h net/if_tun.h linux/fib_rules.h) AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h) diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index 92f65596ad..0260726b21 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -345,6 +345,46 @@ START_TEST(test_memstr) } END_TEST +/******************************************************************************* + * utils_memrchr + */ + +static struct { + char *s; + int c; + size_t n; + int offset; +} memrchr_data[] = { + {NULL, 'f', 0, -1}, + {NULL, 'f', 3, -1}, + {"", 'f', 0, -1}, + {"", '\0', 1, 0}, + {"foo", '\0', 3, -1}, + {"foo", '\0', 4, 3}, + {"foo", 'f', 3, 0}, + {"foo", 'o', 3, 2}, + {"foo", 'o', 2, 1}, + {"foo", 'o', 1, -1}, + {"foo", 'o', 0, -1}, + {"foo", 'x', 3, -1}, +}; + +START_TEST(test_utils_memrchr) +{ + void *ret; + + ret = utils_memrchr(memrchr_data[_i].s, memrchr_data[_i].c, memrchr_data[_i].n); + if (memrchr_data[_i].offset >= 0) + { + ck_assert(ret == memrchr_data[_i].s + memrchr_data[_i].offset); + } + else + { + ck_assert(ret == NULL); + } +} +END_TEST + /******************************************************************************* * translate */ @@ -673,6 +713,10 @@ Suite *utils_suite_create() tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data)); suite_add_tcase(s, tc); + tc = tcase_create("utils_memrchr"); + tcase_add_loop_test(tc, test_utils_memrchr, 0, countof(memrchr_data)); + suite_add_tcase(s, tc); + tc = tcase_create("translate"); tcase_add_loop_test(tc, test_translate, 0, countof(translate_data)); suite_add_tcase(s, tc); diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 406c5c8112..fe80edb823 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -103,7 +103,7 @@ void memwipe_noinline(void *ptr, size_t n) */ void *memstr(const void *haystack, const char *needle, size_t n) { - unsigned const char *pos = haystack; + const u_char *pos = haystack; size_t l; if (!haystack || !needle || (l = strlen(needle)) == 0) @@ -120,6 +120,28 @@ void *memstr(const void *haystack, const char *needle, size_t n) return NULL; } +/** + * Described in header. + */ +void *utils_memrchr(const void *s, int c, size_t n) +{ + const u_char *pos; + + if (!s || !n) + { + return NULL; + } + + for (pos = s + n - 1; pos >= (u_char*)s; pos--) + { + if (*pos == (u_char)c) + { + return (void*)pos; + } + } + return NULL; +} + /** * Described in header. */ diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index 4c113900e3..a55e7d831a 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -464,6 +464,20 @@ static inline void memwipe(void *ptr, size_t n) */ void *memstr(const void *haystack, const char *needle, size_t n); +/** + * Replacement for memrchr(3) if it is not provided by the C library. + * + * @param s start of the memory area to search + * @param c character to search + * @param n length of memory area to search + * @return pointer to the found character or NULL + */ +void *utils_memrchr(const void *s, int c, size_t n); + +#ifndef HAVE_MEMRCHR +#define memrchr(s,c,n) utils_memrchr(s,c,n) +#endif + /** * Translates the characters in the given string, searching for characters * in 'from' and mapping them to characters in 'to'.