From 8a241792f968ed5be6cf4d41e32c0d264f6c0c65 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Mon, 9 Oct 2017 15:20:42 -0700 Subject: [PATCH] Add pg_strnlen() a portable implementation of strlen. As the OS version is likely going to be more optimized, fall back to it if available, as detected by configure. --- configure | 2 +- configure.in | 2 +- src/common/string.c | 20 ++++++++++++++++++++ src/include/common/string.h | 15 +++++++++++++++ src/include/pg_config.h.in | 3 +++ src/include/pg_config.h.win32 | 3 +++ src/port/snprintf.c | 12 ++---------- 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/configure b/configure index 216447e739..a1283c0500 100755 --- a/configure +++ b/configure @@ -8777,7 +8777,7 @@ fi -for ac_func in strerror_r getpwuid_r gethostbyname_r +for ac_func in strerror_r getpwuid_r gethostbyname_r strnlen do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index a2e3d8331a..e1381b4ead 100644 --- a/configure.in +++ b/configure.in @@ -961,7 +961,7 @@ LIBS="$LIBS $PTHREAD_LIBS" AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([ pthread.h not found; use --disable-thread-safety to disable thread safety])]) -AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r]) +AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r strnlen]) # Do test here with the proper thread flags PGAC_FUNC_STRERROR_R_INT diff --git a/src/common/string.c b/src/common/string.c index 159d9ea7b6..901821f3d8 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -41,3 +41,23 @@ pg_str_endswith(const char *str, const char *end) str += slen - elen; return strcmp(str, end) == 0; } + + +/* + * Portable version of posix' strnlen. + * + * Returns the number of characters before a null-byte in the string pointed + * to by str, unless there's no null-byte before maxlen. In the latter case + * maxlen is returned. + */ +#ifndef HAVE_STRNLEN +size_t +pg_strnlen(const char *str, size_t maxlen) +{ + const char *p = str; + + while (maxlen-- > 0 && *p) + p++; + return p - str; +} +#endif diff --git a/src/include/common/string.h b/src/include/common/string.h index 5f3ea71d61..3d46b80918 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -12,4 +12,19 @@ extern bool pg_str_endswith(const char *str, const char *end); +/* + * Portable version of posix' strnlen. + * + * Returns the number of characters before a null-byte in the string pointed + * to by str, unless there's no null-byte before maxlen. In the latter case + * maxlen is returned. + * + * Use the system strnlen if provided, it's likely to be faster. + */ +#ifdef HAVE_STRNLEN +#define pg_strnlen(str, maxlen) strnlen(str, maxlen) +#else +extern size_t pg_strnlen(const char *str, size_t maxlen); +#endif + #endif /* COMMON_STRING_H */ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 368a297e6d..d20cc47fde 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -496,6 +496,9 @@ /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + /* Define to use have a strong random number source */ #undef HAVE_STRONG_RANDOM diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 3537b6f704..58eef0a538 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -345,6 +345,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN + /* Define to use have a strong random number source */ #define HAVE_STRONG_RANDOM 1 diff --git a/src/port/snprintf.c b/src/port/snprintf.c index 231e5d6bdb..531d2c5ee3 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -43,6 +43,8 @@ #endif #include +#include "common/string.h" + #ifndef NL_ARGMAX #define NL_ARGMAX 16 #endif @@ -790,16 +792,6 @@ bad_format: target->failed = true; } -static size_t -pg_strnlen(const char *str, size_t maxlen) -{ - const char *p = str; - - while (maxlen-- > 0 && *p) - p++; - return p - str; -} - static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target) -- 2.40.0