[libcxx-commits] [libcxx] 64e4dd3 - [libcxx] [test] Fix back-to-back use of get_temp_file_name() on Windows

Martin Storsjö via libcxx-commits libcxx-commits at lists.llvm.org
Mon Apr 11 09:48:41 PDT 2022


Author: Martin Storsjö
Date: 2022-04-11T19:46:40+03:00
New Revision: 64e4dd329c0c9d4c462594df004afd3102a54412

URL: https://github.com/llvm/llvm-project/commit/64e4dd329c0c9d4c462594df004afd3102a54412
DIFF: https://github.com/llvm/llvm-project/commit/64e4dd329c0c9d4c462594df004afd3102a54412.diff

LOG: [libcxx] [test] Fix back-to-back use of get_temp_file_name() on Windows

On non-Windows platforms, get_temp_file_name() uses `mkstemp()`,
which picks a unique name and creates a file atomically. The
Windows implementation uses `_mktemp_s()`, which doesn't create the
file. The documentation of `_mktemp_s()` also says that by design,
the function uses the same pattern within a process, as long as that
file doesn't exist.

Thus previously, two consecutive calls to `get_temp_file_name()`
on Windows returned the same file name.

Try to create the suggested temp file with `_O_EXCL` (marking the
file name as already used for future calls to `_mktemp_s`) and retry
if we weren't able to exclusively create the file.

This fixes the test failures on Windows observed in D122257.

Differential Revision: https://reviews.llvm.org/D122612

Added: 
    

Modified: 
    libcxx/test/support/platform_support.h

Removed: 
    


################################################################################
diff  --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h
index e18c3114c7561..ce7a04b2a3087 100644
--- a/libcxx/test/support/platform_support.h
+++ b/libcxx/test/support/platform_support.h
@@ -39,6 +39,8 @@
 #include <string>
 #if defined(_WIN32)
 #   include <io.h> // _mktemp_s
+#   include <fcntl.h> // _O_EXCL, ...
+#   include <sys/stat.h> // _S_IREAD, ...
 #else
 #   include <unistd.h> // close
 #endif
@@ -54,9 +56,18 @@ inline
 std::string get_temp_file_name()
 {
 #if defined(_WIN32)
-    char Name[] = "libcxx.XXXXXX";
-    if (_mktemp_s(Name, sizeof(Name)) != 0) abort();
-    return Name;
+    while (true) {
+        char Name[] = "libcxx.XXXXXX";
+        if (_mktemp_s(Name, sizeof(Name)) != 0) abort();
+        int fd = _open(Name, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
+        if (fd != -1) {
+            _close(fd);
+            return Name;
+        }
+        if (errno == EEXIST)
+            continue;
+        abort();
+    }
 #else
     std::string Name;
     int FD = -1;


        


More information about the libcxx-commits mailing list