diff --git a/CMakeLists.txt b/CMakeLists.txt index e44f99b..e4f12a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,9 +265,33 @@ endif(WIN32 OR CYGWIN) # requirements include(CheckSymbolExists) + # Some platforms provide their own strlcpy & strlcat. (BSD, MacOSX) -# Others don't so we provide our own. (Most, but not all Linux) -# Define the preprocessor macro so libgps does not supply its own version. +# Others don't so we provide our own. (Windows, most, but not all Linux) +# Here we detect whether these are provided by the OS and set a symbol +# so that: +# (1) libgps does not supply its own version. +# (2) we know whether we need to supply our own copy. +# +# This was all working fine until these were added to the gnu c library 2.38. +# References: +* - https://www.gnu.org/software/libc/sources.html +# - https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=NEWS;hb=HEAD +# +# This test is not detecting them for glibc 2.38 resulting in a conflict. +# Why? Are they declared in a different file or in some strange way? +# +# This is how they are declared in include/string.h: +# +# extern __typeof (strlcpy) __strlcpy; +# libc_hidden_proto (__strlcpy) +# extern __typeof (strlcat) __strlcat; +# libc_hidden_proto (__strlcat) +# +# Apparently cmake does not recognize this style. +# Keep this here for BSD type systems where it behaves as expected. +# We will need to add a hack in direwolf.h to define these if glibc version >= 2.38. + check_symbol_exists(strlcpy string.h HAVE_STRLCPY) if(HAVE_STRLCPY) add_compile_options(-DHAVE_STRLCPY) diff --git a/src/direwolf.h b/src/direwolf.h index 3a47398..69b0952 100644 --- a/src/direwolf.h +++ b/src/direwolf.h @@ -278,6 +278,8 @@ typedef pthread_mutex_t dw_mutex_t; /* Platform differences for string functions. */ +// Windows is missing a few which are available on Unix/Linux platforms. +// We provide our own copies when building on Windows. #if __WIN32__ char *strsep(char **stringp, const char *delim); @@ -285,13 +287,49 @@ char *strtok_r(char *str, const char *delim, char **saveptr); #endif // Don't recall why I added this for everyone rather than only for Windows. +// Potential problem if some C library declares it a little differently. char *strcasestr(const char *S, const char *FIND); -// cmake determines whether strlcpy and strlcat are available -// or if we need to supply our own. +// cmake tries to determine whether strlcpy and strlcat are provided by the C runtime library. +// +// ../CMakeLists.txt:check_symbol_exists(strlcpy string.h HAVE_STRLCPY) +// +// It sets HAVE_STRLCPY and HAVE_STRLCAT if the corresponding functions are declared. +// Unfortunately this does not work right for glibc 2.38 which declares the functions +// like this: +// +// extern __typeof (strlcpy) __strlcpy; +// libc_hidden_proto (__strlcpy) +// extern __typeof (strlcat) __strlcat; +// libc_hidden_proto (__strlcat) +// +// Rather than the normal way found in earlier versions: +// +// extern char *strcpy (char *__restrict __dest, const char *__restrict __src) +// +// Perhaps a later version of cmake will recognize this form but the version I'm +// using does not. +// So, our work around is to assume these functions are available for glibc >= 2.38. +// +// In theory, cmake should be able to find the version of the C runtime library, +// but I could not get it to work. So we have the test here. We will still build +// own library with the strl... functions but this does not cause a problem +// because they have special debug names which will not cause a conflict. + +#ifdef __GLIBC__ +#if (__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 38)) +// These functions first added in 2.38. +//#warning "DEBUG - glibc >= 2.38" +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#else +//#warning "DEBUG - glibc < 2.38" +#endif +#endif #define DEBUG_STRL 1 // Extra Debug version when using our own strlcpy, strlcat. + // Should be ignored if not supplying our own. #ifndef HAVE_STRLCPY // Need to supply our own. #if DEBUG_STRL