diff --git a/lib/Makefile.in b/lib/Makefile.in index a39102957..b3c7e6d28 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -3452,6 +3452,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \ -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ @@ -3948,6 +3949,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ diff --git a/gnulib-tests/strerror_r.c b/gnulib-tests/strerror_r.c index f0244520b..90043c223 100644 --- a/gnulib-tests/strerror_r.c +++ b/gnulib-tests/strerror_r.c @@ -34,33 +34,26 @@ #include "strerror-override.h" -#if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */ +#if STRERROR_R_CHAR_P -# define USE_XPG_STRERROR_R 1 -extern -#ifdef __cplusplus -"C" -#endif -int __xpg_strerror_r (int errnum, char *buf, size_t buflen); +# if HAVE___XPG_STRERROR_R +_GL_EXTERN_C int __xpg_strerror_r (int errnum, char *buf, size_t buflen); +# endif -#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) +#elif HAVE_DECL_STRERROR_R -/* The system's strerror_r function is OK, except that its third argument +/* The system's strerror_r function's API is OK, except that its third argument is 'int', not 'size_t', or its return type is wrong. */ # include -# define USE_SYSTEM_STRERROR_R 1 - -#else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */ +#else /* Use the system's strerror(). Exclude glibc and cygwin because the system strerror_r has the wrong return type, and cygwin 1.7.9 strerror_r clobbers strerror. */ # undef strerror -# define USE_SYSTEM_STRERROR 1 - # if defined __NetBSD__ || defined __hpux || (defined _WIN32 && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__ /* No locking needed. */ @@ -166,22 +159,28 @@ strerror_r (int errnum, char *buf, size_t buflen) int ret; int saved_errno = errno; -#if USE_XPG_STRERROR_R +#if STRERROR_R_CHAR_P { + ret = 0; + +# if HAVE___XPG_STRERROR_R ret = __xpg_strerror_r (errnum, buf, buflen); if (ret < 0) ret = errno; +# endif + if (!*buf) { /* glibc 2.13 would not touch buf on err, so we have to fall back to GNU strerror_r which always returns a thread-safe untruncated string to (partially) copy into our buf. */ - safe_copy (buf, buflen, strerror_r (errnum, buf, buflen)); + char *errstring = strerror_r (errnum, buf, buflen); + ret = errstring ? safe_copy (buf, buflen, errstring) : errno; } } -#elif USE_SYSTEM_STRERROR_R +#elif HAVE_DECL_STRERROR_R if (buflen > INT_MAX) buflen = INT_MAX; @@ -245,7 +244,7 @@ strerror_r (int errnum, char *buf, size_t buflen) } # endif -#else /* USE_SYSTEM_STRERROR */ +#else /* strerror_r is not declared. */ /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ diff --git a/lib/string.in.h b/lib/string.in.h index fa2e40c25..8977153c8 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -47,9 +47,6 @@ /* NetBSD 5.0 mis-defines NULL. */ #include -/* Get free(). */ -#include - /* MirBSD defines mbslen as a macro. */ #if @GNULIB_MBSLEN@ && defined __MirBSD__ # include @@ -86,6 +83,13 @@ /* The definition of _GL_WARN_ON_USE is copied here. */ +/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */ +#if (@REPLACE_FREE@ && !defined free \ + && !(defined __cplusplus && defined GNULIB_NAMESPACE)) +_GL_EXTERN_C void free (void *); +# define free rpl_free +#endif +_GL_EXTERN_C void free (void *); /* Clear a block of memory. The compiler will not delete a call to this function, even if the block is dead after the call. */ diff --git a/lib/wchar.in.h b/lib/wchar.in.h index be5d36c8d..acb9d4ea6 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -72,9 +72,6 @@ # include #endif -/* Get free(). */ -#include - /* Include the original if it exists. Some builds of uClibc lack it. */ /* The include_next requires a split double-inclusion guard. */ @@ -149,6 +146,13 @@ typedef int rpl_mbstate_t; # endif #endif +/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */ +#if (@REPLACE_FREE@ && !defined free \ + && !(defined __cplusplus && defined GNULIB_NAMESPACE)) +_GL_EXTERN_C void free (void *); +# define free rpl_free +#endif +_GL_EXTERN_C void free (void *); /* Convert a single-byte character to a wide character. */ #if @GNULIB_BTOWC@