diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 36 | ||||
-rw-r--r-- | src/common/compat.h | 3 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index 85db2b6ad4..f6fdda6e0a 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -13,7 +13,9 @@ const char compat_c_id[] = "$Id$"; * the platform. **/ -/* This is required on rh7 to make strptime not complain. */ +/* This is required on rh7 to make strptime not complain. + * We also need it to make memmem get defined (where available) + */ #define _GNU_SOURCE #include "orconfig.h" @@ -134,6 +136,38 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args) return r; } +/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at + * <b>needle</b>, return a pointer to the first occurence of the needle + * within the haystack, or NULL if there is no such occurrence. + * + * Requires that nlen be greater than zero. + */ +const void * +tor_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) +{ +#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) + tor_assert(nlen); + return memmem(haystack, hlen, needle, nlen); +#else + /* This isn't as fast as the GLIBC implementation, but it doesn't need to be. */ + const void *p, *end; + char first; + tor_assert(nlen); + + p = haystack; + end = haystack + hlen; + first = *(const char*)needle; + while ((p = memchr(p, first, end-p))) { + if (end-p >= nlen) + return NULL; + if (!memcmp(p, needle, nlen)) + return p; + ++p; + } + return NULL; +#endif +} + /** Take a filename and return a pointer to its final element. This * function is called on __FILE__ to fix a MSVC nit where __FILE__ * contains the full path to the file. This is bad, because it diff --git a/src/common/compat.h b/src/common/compat.h index 8f44e93857..dbf8828ab3 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -87,6 +87,9 @@ int tor_snprintf(char *str, size_t size, const char *format, ...) CHECK_PRINTF(3,4); int tor_vsnprintf(char *str, size_t size, const char *format, va_list args); +const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, + size_t nlen); + #define TOR_ISAPLHA(c) isalpha((int)(unsigned char)(c)) #define TOR_ISALNUM(c) isalnum((int)(unsigned char)(c)) #define TOR_ISSPACE(c) isspace((int)(unsigned char)(c)) |