From d74a4ea30d5d5d06cd4cc22a8394796ff943c358 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 23 Jun 2022 18:09:35 +0200 Subject: [PATCH 1/2] Add wxCHECK_GLIBC_VERSION() and cleanup glibc version checks Use this macro where possible and simplify the checks in a couple of places where it isn't (because we're checking for an exact glibc version). No real changes. --- include/wx/private/glibc.h | 25 +++++++++++++++++++++++++ include/wx/wxcrtbase.h | 2 +- src/common/strconv.cpp | 3 ++- src/unix/sockunix.cpp | 4 +--- src/unix/utilsunx.cpp | 4 ++-- tests/intl/intltest.cpp | 4 +++- 6 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 include/wx/private/glibc.h diff --git a/include/wx/private/glibc.h b/include/wx/private/glibc.h new file mode 100644 index 0000000000..94b8526565 --- /dev/null +++ b/include/wx/private/glibc.h @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/glibc.h +// Purpose: glibc-specific private wx header +// Author: Vadim Zeitlin +// Created: 2022-06-23 +// Copyright: (c) 2022 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_GLIBC_H_ +#define _WX_PRIVATE_GLIBC_H_ + +// Ensure that a header include __GLIBC__ is defined. +#include + +// Macro for testing glibc version similar to wxCHECK_GCC_VERSION(). +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) + #define wxCHECK_GLIBC_VERSION( major, minor ) \ + ( ( __GLIBC__ > (major) ) \ + || ( __GLIBC__ == (major) && __GLIBC_MINOR__ >= (minor) ) ) +#else + #define wxCHECK_GLIBC_VERSION( major, minor ) 0 +#endif + +#endif // _WX_PRIVATE_GLIBC_H_ diff --git a/include/wx/wxcrtbase.h b/include/wx/wxcrtbase.h index 8545bad304..7887324206 100644 --- a/include/wx/wxcrtbase.h +++ b/include/wx/wxcrtbase.h @@ -594,7 +594,7 @@ WXDLLIMPEXP_BASE size_t wxCRT_StrftimeW(wchar_t *s, size_t max, #define wxCRT_IsxdigitW(c) iswxdigit(c) #ifdef __GLIBC__ - #if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) + #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) /* /usr/include/wctype.h incorrectly declares translations */ /* tables which provokes tons of compile-time warnings -- try */ /* to correct this */ diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 84e96e5fc4..c0677938f7 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -38,6 +38,7 @@ #ifdef HAVE_ICONV #include #include "wx/thread.h" + #include "wx/private/glibc.h" #endif #include "wx/encconv.h" @@ -2037,7 +2038,7 @@ wxMBConvUTF32swap::FromWChar(char *dst, size_t dstLen, // bytes-left-in-input buffer is non-zero. Hence, this alternative test for // iconv() failure. // [This bug does not appear in glibc 2.2.] -#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1 +#if wxCHECK_GLIBC_VERSION(2, 0) && !wxCHECK_GLIBC_VERSION(2, 2) #define ICONV_FAILED(cres, bufLeft) ((cres == (size_t)-1) && \ (errno != E2BIG || bufLeft != 0)) #else diff --git a/src/unix/sockunix.cpp b/src/unix/sockunix.cpp index e1ffee352a..ae15adfb7c 100644 --- a/src/unix/sockunix.cpp +++ b/src/unix/sockunix.cpp @@ -32,9 +32,7 @@ # define WX_SOCKLEN_T unsigned int #else # ifdef __GLIBC__ -# if __GLIBC__ == 2 -# define WX_SOCKLEN_T socklen_t -# endif +# define WX_SOCKLEN_T socklen_t # elif defined(__WXMAC__) # define WX_SOCKLEN_T socklen_t # else diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index c1cae83f15..ac5181e187 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -54,6 +54,7 @@ #include "wx/private/selectdispatcher.h" #include "wx/private/fdiodispatcher.h" +#include "wx/private/glibc.h" #include "wx/unix/private/execute.h" #include "wx/unix/pipe.h" #include "wx/unix/private.h" @@ -216,8 +217,7 @@ void wxMilliSleep(unsigned long milliseconds) void wxSecureZeroMemory(void* v, size_t n) { -#if (defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) || \ +#if wxCHECK_GLIBC_VERSION(2, 25) || \ (defined(__FreeBSD__) && __FreeBSD__ >= 11) // This non-standard function is somewhat widely available elsewhere too, // but may be found in a non-standard header file, or in a library that is diff --git a/tests/intl/intltest.cpp b/tests/intl/intltest.cpp index 685ad5bb71..41e550baba 100644 --- a/tests/intl/intltest.cpp +++ b/tests/intl/intltest.cpp @@ -20,6 +20,8 @@ #include "wx/intl.h" #include "wx/uilocale.h" +#include "wx/private/glibc.h" + #if wxUSE_INTL // ---------------------------------------------------------------------------- @@ -175,7 +177,7 @@ void IntlTestCase::DateTimeFmtFrench() #ifdef __GLIBC__ // Versions of glibc up to 2.7 wrongly used periods for French locale // separator. -#if __GLIBC__ > 2 || __GLIBC_MINOR__ >= 8 +#if wxCHECK_GLIBC_VERSION(2, 8) static const char *FRENCH_DATE_FMT = "%d/%m/%Y"; #else static const char *FRENCH_DATE_FMT = "%d.%m.%Y"; From 5333897535a5c66a20f5253aa0659dd415377459 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 23 Jun 2022 18:16:43 +0200 Subject: [PATCH 2/2] Fix compilation of wxThread::SetNameForCurrent() with older glibc Check if we have glibc 2.12 before using pthread_setname_np() and fall back on prctl(PR_SET_NAME) if we can use that. Co-Authored-by: Lauri Nurmi Closes #22559. --- src/unix/threadpsx.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index 4876ac2fe2..2cd33eed2f 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -64,6 +64,18 @@ // we use wxFFile under Linux in GetCPUCount() #ifdef __LINUX__ #include "wx/ffile.h" + #include "wx/private/glibc.h" + #if wxCHECK_GLIBC_VERSION(2, 12) + #define wxHAVE_PTHREAD_SETNAME_NP + #define wxCAN_SET_LINUX_THREAD_NAME + #else + #include + + // This is only available since Linux 2.6.9 + #ifdef PR_SET_NAME + #define wxCAN_SET_LINUX_THREAD_NAME + #endif + #endif #endif // We don't provide wxAtomicLong and it doesn't seem really useful to add it @@ -1696,12 +1708,16 @@ bool wxThread::SetNameForCurrent(const wxString &name) #if defined(__DARWIN__) pthread_setname_np(name.utf8_str()); return true; -#elif defined(__LINUX__) +#elif defined(__LINUX__) && defined(wxCAN_SET_LINUX_THREAD_NAME) // Linux doesn't allow names longer than 15 bytes. char truncatedName[16] = { 0 }; strncpy(truncatedName, name.utf8_str(), 15); - return pthread_setname_np(pthread_self(), truncatedName) == 0; + #ifdef wxHAVE_PTHREAD_SETNAME_NP + return pthread_setname_np(pthread_self(), truncatedName) == 0; + #else + return prctl(PR_SET_NAME, (unsigned long)(void*)truncatedName, 0, 0, 0); + #endif #else wxUnusedVar(name); wxLogDebug("No implementation for wxThread::SetName() on this OS.");