From: Mark Andrews Date: Thu, 10 Apr 2003 04:47:56 +0000 (+0000) Subject: 1457. [port] Provide strlcat() and strlcpy() for platforms without X-Git-Tag: v9.2.3rc1~104^2~39 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=935000aa6e2b9d08f363b2e698a258a458a5a7cf;p=thirdparty%2Fbind9.git 1457. [port] Provide strlcat() and strlcpy() for platforms without them. --- diff --git a/CHANGES b/CHANGES index ec6b57f8245..bb714be460c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1457. [port] Provide strlcat() and strlcpy() for platforms without + them. + 1456. [contrib] gen-data-queryperf.py from Stephane Bortzmeyer. 1455. [bug] missing from server grammar in diff --git a/configure b/configure index ccebab0feb7..5f813580941 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.341 . +# From configure.in Revision: 1.342 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53. # @@ -12945,6 +12945,187 @@ echo "${ECHO_T}no" >&6; ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + +echo "$as_me:$LINENO: checking for strlcpy" >&5 +echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6 +if test "${ac_cv_func_strlcpy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* From autoconf 2.57 */ +/* Define strlcpy to an innocuous variant, in case declares strlcpy. + For example, HP-UX 11i declares gettimeofday. */ +#define strlcpy innocuous_strlcpy + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strlcpy (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strlcpy + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strlcpy (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strlcpy) || defined (__stub___strlcpy) +choke me +#else +char (*f) () = strlcpy; +#endif +#ifdef __cplusplus +} +#endif + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +return f != strlcpy; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strlcpy=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_strlcpy=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strlcpy" >&5 +echo "${ECHO_T}$ac_cv_func_strlcpy" >&6 +if test $ac_cv_func_strlcpy = yes; then + ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY" +else + ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1" +fi + + + +echo "$as_me:$LINENO: checking for strlcat" >&5 +echo $ECHO_N "checking for strlcat... $ECHO_C" >&6 +if test "${ac_cv_func_strlcat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* From autoconf 2.57 */ +/* Define strlcat to an innocuous variant, in case declares strlcat. + For example, HP-UX 11i declares gettimeofday. */ +#define strlcat innocuous_strlcat + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strlcat (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strlcat + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strlcat (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strlcat) || defined (__stub___strlcat) +choke me +#else +char (*f) () = strlcat; +#endif +#ifdef __cplusplus +} +#endif + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +return f != strlcat; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strlcat=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_strlcat=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strlcat" >&5 +echo "${ECHO_T}$ac_cv_func_strlcat" >&6 +if test $ac_cv_func_strlcat = yes; then + ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT" +else + ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1" +fi + + + echo "$as_me:$LINENO: checking for vsnprintf" >&5 echo $ECHO_N "checking for vsnprintf... $ECHO_C" >&6 if test "${ac_cv_func_vsnprintf+set}" = set; then @@ -15225,6 +15406,8 @@ s,@ISC_LWRES_GETIPNODEPROTO@,$ISC_LWRES_GETIPNODEPROTO,;t t s,@ISC_LWRES_GETADDRINFOPROTO@,$ISC_LWRES_GETADDRINFOPROTO,;t t s,@ISC_LWRES_GETNAMEINFOPROTO@,$ISC_LWRES_GETNAMEINFOPROTO,;t t s,@ISC_PLATFORM_NEEDSTRSEP@,$ISC_PLATFORM_NEEDSTRSEP,;t t +s,@ISC_PLATFORM_NEEDSTRLCPY@,$ISC_PLATFORM_NEEDSTRLCPY,;t t +s,@ISC_PLATFORM_NEEDSTRLCAT@,$ISC_PLATFORM_NEEDSTRLCAT,;t t s,@ISC_PLATFORM_NEEDVSNPRINTF@,$ISC_PLATFORM_NEEDVSNPRINTF,;t t s,@ISC_EXTRA_OBJS@,$ISC_EXTRA_OBJS,;t t s,@ISC_EXTRA_SRCS@,$ISC_EXTRA_SRCS,;t t diff --git a/configure.in b/configure.in index b045a23f889..2ebfe3b30a8 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl AC_DIVERT_POP()dnl -AC_REVISION($Revision: 1.341 $) +AC_REVISION($Revision: 1.342 $) AC_INIT(lib/dns/name.c) AC_PREREQ(2.13) @@ -1573,14 +1573,25 @@ AC_MSG_CHECKING(for correctly declared strsep()) AC_TRY_LINK([#include ], [char *sp; char *foo = strsep(&sp, ".");], [AC_MSG_RESULT(yes); ISC_PLATFORM_NEEDSTRSEP="#undef ISC_PLATFORM_NEEDSTRSEP"], [AC_MSG_RESULT(no); ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRSEP) + +AC_CHECK_FUNC(strlcpy, + [ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY"], + [ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRLCPY) + +AC_CHECK_FUNC(strlcat, + [ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT"], + [ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRLCAT) AC_CHECK_FUNC(vsnprintf, [ISC_PLATFORM_NEEDVSNPRINTF="#undef ISC_PLATFORM_NEEDVSNPRINTF"], [ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS print.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS print.c" ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1"]) -AC_SUBST(ISC_PLATFORM_NEEDSTRSEP) AC_SUBST(ISC_PLATFORM_NEEDVSNPRINTF) + AC_CHECK_FUNC(strerror, AC_DEFINE(HAVE_STRERROR)) AC_SUBST(ISC_EXTRA_OBJS) diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in index cfaa3c1b53c..836b372dc7f 100644 --- a/lib/isc/include/isc/platform.h.in +++ b/lib/isc/include/isc/platform.h.in @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: platform.h.in,v 1.30 2002/11/26 03:50:07 marka Exp $ */ +/* $Id: platform.h.in,v 1.31 2003/04/10 04:46:27 marka Exp $ */ #ifndef ISC_PLATFORM_H #define ISC_PLATFORM_H 1 @@ -106,6 +106,16 @@ */ @ISC_PLATFORM_NEEDSTRSEP@ +/* + * If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined. + */ +@ISC_PLATFORM_NEEDSTRLCPY@ + +/* + * If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined. + */ +@ISC_PLATFORM_NEEDSTRLCAT@ + /* * Define either ISC_PLATFORM_BSD44MSGHDR or ISC_PLATFORM_BSD43MSGHDR. */ diff --git a/lib/isc/include/isc/string.h b/lib/isc/include/isc/string.h index e16219fdaad..4c34629f751 100644 --- a/lib/isc/include/isc/string.h +++ b/lib/isc/include/isc/string.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: string.h,v 1.9 2001/01/09 21:57:37 bwelling Exp $ */ +/* $Id: string.h,v 1.10 2003/04/10 04:46:27 marka Exp $ */ #ifndef ISC_STRING_H #define ISC_STRING_H 1 @@ -51,6 +51,22 @@ isc_string_separate(char **stringp, const char *delim); #define strsep isc_string_separate #endif +size_t +isc_string_strlcpy(char *dst, const char *src, size_t size); + + +#ifdef ISC_PLATFORM_NEEDSTRLCPY +#define strlcpy isc_string_strlcpy +#endif + + +size_t +isc_string_strlcat(char *dst, const char *src, size_t size); + +#ifdef ISC_PLATFORM_NEEDSTRLCAT +#define strlcat isc_string_strlcat +#endif + ISC_LANG_ENDDECLS #endif /* ISC_STRING_H */ diff --git a/lib/isc/string.c b/lib/isc/string.c index d560da57dcc..2bef81553c3 100644 --- a/lib/isc/string.c +++ b/lib/isc/string.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: string.c,v 1.6 2001/01/09 21:56:30 bwelling Exp $ */ +/* $Id: string.c,v 1.7 2003/04/10 04:46:27 marka Exp $ */ #include @@ -109,3 +109,57 @@ isc_string_separate(char **stringp, const char *delim) { *stringp = NULL; return (string); } + +size_t +strlcpy(char *dst, const char *src, size_t size) +{ + char *d = dst; + const char *s = src; + size_t n = size; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (size != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +size_t +strlcat(char *dst, const char *src, size_t size) +{ + char *d = dst; + const char *s = src; + size_t n = size; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = size - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +}