Rewrite strnlen replacement implementation from 8a241792f9.

The previous placement of the fallback implementation in libpgcommon
was problematic, because libpqport functions need strnlen
functionality.

Move replacement into libpgport. Provide strnlen() under its posix
name, instead of pg_strnlen(). Fix stupid configure bug, executing the
test only when compiled with threading support.

Author: Andres Freund
Discussion: https://postgr.es/m/E1e1gR2-0005fB-SI@gemulon.postgresql.org
This commit is contained in:
Andres Freund 2017-10-10 14:42:16 -07:00
parent fa5e119dc7
commit fffd651e83
10 changed files with 77 additions and 47 deletions

25
configure vendored
View File

@ -8777,7 +8777,7 @@ fi
for ac_func in strerror_r getpwuid_r gethostbyname_r strnlen
for ac_func in strerror_r getpwuid_r gethostbyname_r
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"
@ -13161,6 +13161,16 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_STRLCPY $ac_have_decl
_ACEOF
ac_fn_c_check_decl "$LINENO" "strnlenfrak" "ac_cv_have_decl_strnlen" "$ac_includes_default"
if test "x$ac_cv_have_decl_strnlen" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_STRNLEN $ac_have_decl
_ACEOF
# This is probably only present on macOS, but may as well check always
ac_fn_c_check_decl "$LINENO" "F_FULLFSYNC" "ac_cv_have_decl_F_FULLFSYNC" "#include <fcntl.h>
@ -13528,6 +13538,19 @@ esac
fi
ac_fn_c_check_func "$LINENO" "strnlenfrak" "ac_cv_func_strnlen"
if test "x$ac_cv_func_strnlen" = xyes; then :
$as_echo "#define HAVE_STRNLEN 1" >>confdefs.h
else
case " $LIBOBJS " in
*" strnlen.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
;;
esac
fi
case $host_os in

View File

@ -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 strnlen])
AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r])
# Do test here with the proper thread flags
PGAC_FUNC_STRERROR_R_INT
@ -1422,7 +1422,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include <fcntl.h>])
fi
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
AC_CHECK_DECLS([strlcat, strlcpy])
AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
# This is probably only present on macOS, but may as well check always
AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
@ -1514,7 +1514,7 @@ else
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
fi
AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton mkdtemp random rint srandom strerror strlcat strlcpy])
AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton mkdtemp random rint srandom strerror strlcat strlcpy strnlen])
case $host_os in

View File

@ -21,7 +21,6 @@
#include "postgres.h"
#include "common/string.h"
#include "miscadmin.h"
#include "utils/memdebug.h"
#include "utils/memutils.h"
@ -1089,7 +1088,7 @@ pnstrdup(const char *in, Size len)
{
char *out;
len = pg_strnlen(in, len);
len = strnlen(in, len);
out = palloc(len + 1);
memcpy(out, in, len);

View File

@ -41,23 +41,3 @@ 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

View File

@ -12,19 +12,4 @@
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 */

View File

@ -147,6 +147,10 @@
don't. */
#undef HAVE_DECL_STRLCPY
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
don't. */
#undef HAVE_DECL_STRNLEN
/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
don't. */
#undef HAVE_DECL_SYS_SIGLIST

View File

@ -99,6 +99,10 @@
don't. */
#define HAVE_DECL_SNPRINTF 1
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
don't. */
#define HAVE_DECL_STRNLEN 1
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#define HAVE_DECL_VSNPRINTF 1
@ -255,6 +259,9 @@
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
/* #undef HAVE_PAM_PAM_APPL_H */
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `poll' function. */
/* #undef HAVE_POLL */
@ -345,9 +352,6 @@
/* Define to 1 if you have the <string.h> 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

View File

@ -406,6 +406,10 @@ extern size_t strlcat(char *dst, const char *src, size_t siz);
extern size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#if !HAVE_DECL_STRNLEN
extern size_t strnlen(const char *str, size_t maxlen);
#endif
#if !defined(HAVE_RANDOM)
extern long random(void);
#endif

View File

@ -43,8 +43,6 @@
#endif
#include <sys/param.h>
#include "common/string.h"
#ifndef NL_ARGMAX
#define NL_ARGMAX 16
#endif
@ -804,7 +802,7 @@ fmtstr(char *value, int leftjust, int minlen, int maxwidth,
* than that.
*/
if (pointflag)
vallen = pg_strnlen(value, maxwidth);
vallen = strnlen(value, maxwidth);
else
vallen = strlen(value);

33
src/port/strnlen.c Normal file
View File

@ -0,0 +1,33 @@
/*-------------------------------------------------------------------------
*
* strnlen.c
* Fallback implementation of strnlen().
*
*
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/port/strnlen.c
*
*-------------------------------------------------------------------------
*/
#include "c.h"
/*
* Implementation of posix' strnlen for systems where it's not available.
*
* 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.
*/
size_t
strnlen(const char *str, size_t maxlen)
{
const char *p = str;
while (maxlen-- > 0 && *p)
p++;
return p - str;
}