소스 검색

Merge topic 'sunos-i386-mkdtemp' into release-4.0

4db9e1009d Solaris: Backport our mkdtemp code paths to SunOS 5.10 i386
f189e64126 Tests: Add cases covering our mkdtemp code paths

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !10313
Brad King 11 달 전
부모
커밋
599ad2b12d

+ 4 - 0
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)

+ 32 - 1
Source/cmSystemTools.cxx

@@ -141,6 +141,14 @@
 #  include <sys/utsname.h>
 #endif
 
+#if defined(CMAKE_BOOTSTRAP) && defined(__sun) && defined(__i386)
+#  define CMAKE_NO_MKDTEMP
+#endif
+
+#ifdef CMAKE_NO_MKDTEMP
+#  include <dlfcn.h>
+#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);
     }

+ 1 - 0
Tests/CMakeLib/CMakeLists.txt

@@ -33,6 +33,7 @@ set(CMakeLib_TESTS
   testFindPackageCommand.cxx
   testUVHandlePtr.cxx
   testUVJobServerClient.cxx
+  testUVPatches.cxx
   testUVProcessChain.cxx
   testUVRAII.cxx
   testUVStreambuf.cxx

+ 23 - 0
Tests/CMakeLib/testSystemTools.cxx

@@ -96,11 +96,34 @@ static bool testStrVersCmp()
   return true;
 }
 
+static bool testMakeTempDirectory()
+{
+  std::cout << "testMakeTempDirectory()\n";
+
+  static std::string const kTemplate = "testMakeTempDirectory-XXXXXX";
+  std::string tempDir = kTemplate;
+  cmsys::Status status = cmSystemTools::MakeTempDirectory(tempDir);
+  if (!status) {
+    std::cout << "cmSystemTools::MakeTempDirectory failed on \"" << tempDir
+              << "\": " << status.GetString() << '\n';
+    return false;
+  }
+  if (!cmSystemTools::FileIsDirectory(tempDir)) {
+    std::cout << "cmSystemTools::MakeTempDirectory did not create \""
+              << tempDir << '\n';
+    return false;
+  }
+  cmSystemTools::RemoveADirectory(tempDir);
+  ASSERT_TRUE(tempDir != kTemplate);
+  return true;
+}
+
 int testSystemTools(int /*unused*/, char* /*unused*/[])
 {
   return runTests({
     testUpperCase,
     testVersionCompare,
     testStrVersCmp,
+    testMakeTempDirectory,
   });
 }

+ 46 - 0
Tests/CMakeLib/testUVPatches.cxx

@@ -0,0 +1,46 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <string>
+
+#include <cm3p/uv.h>
+
+#include "cmSystemTools.h"
+
+#include "testCommon.h"
+
+static bool test_uv_fs_mkdtemp()
+{
+  std::cout << "test_uv_fs_mkdtemp()\n";
+  static std::string const kTemplate = "test-uv_fs_mkdtemp-XXXXXX";
+  std::string tempDir;
+  uv_fs_t tempDirReq;
+  tempDirReq.data = &tempDir;
+  uv_loop_t* loop = uv_default_loop();
+  int r =
+    uv_fs_mkdtemp(loop, &tempDirReq, kTemplate.c_str(), [](uv_fs_t* req) {
+      if (req->data && req->path) {
+        *static_cast<std::string*>(req->data) = req->path;
+      }
+    });
+  ASSERT_EQUAL(r, 0);
+  uv_run(loop, UV_RUN_DEFAULT);
+  uv_fs_req_cleanup(&tempDirReq);
+  if (!cmSystemTools::FileIsDirectory(tempDir)) {
+    std::cout << "cmSystemTools::MakeTempDirectory did not create \""
+              << tempDir << '\n';
+    return false;
+  }
+  cmSystemTools::RemoveADirectory(tempDir);
+  ASSERT_TRUE(tempDir != kTemplate);
+  return true;
+}
+
+int testUVPatches(int /*unused*/, char* /*unused*/[])
+{
+  return runTests({
+    test_uv_fs_mkdtemp,
+  });
+}

+ 4 - 0
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

+ 20 - 3
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