tint/win: fix TmpFilePath asserting in some msvc crts
We were using the "x" flag for exclusive mode in the call to fopen_s,
but this seems not to be supported in all c runtimes. For instance, we
get this error when using the debug crt on the LUCI windows bots:
```
minkernel\crts\ucrt\inc\corecrt_internal_stdio.h(656) : Assertion failed: ("Invalid file open mode", 0)
```
Replaced this with MS-specific _sopen_s that accepts flags
`_O_CREAT | _O_EXCL` to create a file in exclusive mode, failing if it
already exists.
Bug: dawn:2435
Change-Id: I1ef997846c6d034dea4cae619cd85c6b6e9d9295
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/179140
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/tint/utils/file/tmpfile_windows.cc b/src/tint/utils/file/tmpfile_windows.cc
index 486c2ea..d4112eb 100644
--- a/src/tint/utils/file/tmpfile_windows.cc
+++ b/src/tint/utils/file/tmpfile_windows.cc
@@ -29,6 +29,8 @@
#include "src/tint/utils/file/tmpfile.h"
+#include <fcntl.h>
+#include <io.h>
#include <stdio.h>
#include <cstdio>
@@ -42,11 +44,16 @@
// creating it, failing if it already exists.
while (tmpnam_s(name, L_tmpnam - 1) == 0) {
std::string name_with_ext = std::string(name) + ext;
- FILE* f = nullptr;
- // The "x" arg forces the function to fail if the file already exists.
- fopen_s(&f, name_with_ext.c_str(), "wbx");
- if (f) {
- fclose(f);
+
+ // Use MS-specific _sopen_s as it allows us to create the file in exclusive mode (_O_EXCL)
+ // so that it returns an error if the file already exists.
+ int fh = 0;
+ errno_t e = _sopen_s(&fh, name_with_ext.c_str(), //
+ /* _OpenFlag */ _O_RDWR | _O_CREAT | _O_EXCL, //
+ /* _ShareFlag */ _SH_DENYNO,
+ /* _PermissionMode */ _S_IREAD | _S_IWRITE);
+ if (e == 0) {
+ _close(fh);
return name_with_ext;
}
}