From 4db9e1009d8a4aa3a46c9d35afaa265a8c2201a6 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Feb 2025 17:38:05 -0500 Subject: Solaris: Backport our mkdtemp code paths to SunOS 5.10 i386 `mkdtemp` is not available on this architecture until SunOS 5.11. Look up the symbol at runtime, and if missing, fall back to an approximate implementation. --- Source/CMakeLists.txt | 4 ++++ Source/cmSystemTools.cxx | 33 ++++++++++++++++++++++++++++++++- Utilities/cmlibuv/CMakeLists.txt | 4 ++++ Utilities/cmlibuv/src/unix/fs.c | 23 ++++++++++++++++++++--- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 745c38c..94fa62a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -1030,6 +1030,10 @@ if(WIN32 AND NOT CYGWIN) list(APPEND _tools cmcldeps) endif() +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION STREQUAL "5.10" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "i386") + set_property(SOURCE cmSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_NO_MKDTEMP) +endif() + # Some atomic instructions are implemented using libatomic on some platforms. if(CMake_HAVE_CXX_ATOMIC_LIB) target_link_libraries(CMakeLib PUBLIC atomic) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 065c4e7..8e9deb1 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -141,6 +141,14 @@ # include #endif +#if defined(CMAKE_BOOTSTRAP) && defined(__sun) && defined(__i386) +# define CMAKE_NO_MKDTEMP +#endif + +#ifdef CMAKE_NO_MKDTEMP +# include +#endif + #if defined(_MSC_VER) && _MSC_VER >= 1800 # define CM_WINDOWS_DEPRECATED_GetVersionEx #endif @@ -1369,6 +1377,29 @@ inline int Mkdir(char const* dir, mode_t const* mode) #endif } +#ifdef CMAKE_NO_MKDTEMP +namespace { +char* cm_mkdtemp_fallback(char* template_) +{ + if (mktemp(template_) == nullptr || mkdir(template_, 0700) != 0) { + return nullptr; + } + return template_; +} +using cm_mkdtemp_t = char* (*)(char*); +cm_mkdtemp_t const cm_mkdtemp = []() -> cm_mkdtemp_t { + cm_mkdtemp_t f = (cm_mkdtemp_t)dlsym(RTLD_DEFAULT, "mkdtemp"); + dlerror(); // Ignore/cleanup dlsym errors. + if (!f) { + f = cm_mkdtemp_fallback; + } + return f; +}(); +} +#else +# define cm_mkdtemp mkdtemp +#endif + cmsys::Status cmSystemTools::MakeTempDirectory(std::string& path, mode_t const* mode) { @@ -1422,7 +1453,7 @@ cmsys::Status cmSystemTools::MakeTempDirectory(char* path, mode_t const* mode) } return cmsys::Status::POSIX(EAGAIN); #else - if (mkdtemp(path)) { + if (cm_mkdtemp(path)) { if (mode) { chmod(path, *mode); } diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index c9b3a2c..8773e56 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -302,6 +302,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") endif() if(CMAKE_SYSTEM_VERSION STREQUAL "5.10") list(APPEND uv_defines SUNOS_NO_IFADDRS) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386") + list(APPEND uv_defines CMAKE_NO_MKDTEMP) + endif() endif() list(APPEND uv_sources src/unix/no-proctitle.c @@ -318,6 +321,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") ) list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED + CMAKE_NO_MKDTEMP ) list(APPEND uv_sources src/unix/hpux.c diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c index e2db3ad..ce7076b 100644 --- a/Utilities/cmlibuv/src/unix/fs.c +++ b/Utilities/cmlibuv/src/unix/fs.c @@ -282,13 +282,30 @@ static ssize_t uv__fs_futime(uv_fs_t* req) { #endif } -#if (defined(__sun) || defined(__hpux)) && (_XOPEN_SOURCE < 600 || defined(CMAKE_BOOTSTRAP)) -static char* uv__mkdtemp(char *template) -{ +#if defined(CMAKE_BOOTSTRAP) && defined(__sun) && defined(__i386) +# define CMAKE_NO_MKDTEMP +#endif + +#if defined(CMAKE_NO_MKDTEMP) +static char* uv__mkdtemp_fallback(char *template) { if (!mktemp(template) || mkdir(template, 0700)) return NULL; return template; } +static char* (*uv__mkdtemp_f)(char*); +static void uv__mkdtemp_initonce(void) { + uv__mkdtemp_f = (char* (*)(char*)) dlsym(RTLD_DEFAULT, "mkdtemp"); + dlerror(); /* Ignore/cleanup dlsym errors. */ + if (uv__mkdtemp_f == NULL) { + uv__mkdtemp_f = uv__mkdtemp_fallback; + } +} +static char* uv__mkdtemp(char *template) +{ + static uv_once_t once = UV_ONCE_INIT; + uv_once(&once, uv__mkdtemp_initonce); + return uv__mkdtemp_f(template); +} #else #define uv__mkdtemp mkdtemp #endif -- cgit v0.12