Skip to content

Commit 3b7b2f2

Browse files
jhuber6mordante
andauthored
[libcxx] Add fallback to standard C when unistd is unavailable (#102005)
Summary: This utility function gets a temp file to use for tests. It either uses WIN32 or POSIX to create it. Some targets only follow the C standard, and this test case will fail. This patch simply adds a fallback that uses the `tmpnam` function from standard C. This function isn't ideal, but it is good enough for our use-case. --------- Co-authored-by: Mark de Wever <[email protected]>
1 parent 394162f commit 3b7b2f2

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

libcxx/test/support/platform_support.h

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
# include <io.h> // _mktemp_s
4141
# include <fcntl.h> // _O_EXCL, ...
4242
# include <sys/stat.h> // _S_IREAD, ...
43-
#else
44-
# include <unistd.h> // close
43+
#elif __has_include(<unistd.h>)
44+
# include <unistd.h> // close
4545
#endif
4646

4747
#if defined(_CS_GNU_LIBC_VERSION)
@@ -55,31 +55,44 @@ extern "C" {
5555
}
5656
#endif
5757

58-
inline
59-
std::string get_temp_file_name()
60-
{
58+
inline std::string get_temp_file_name() {
6159
#if defined(_WIN32)
62-
while (true) {
63-
char Name[] = "libcxx.XXXXXX";
64-
if (_mktemp_s(Name, sizeof(Name)) != 0) abort();
65-
int fd = _open(Name, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
66-
if (fd != -1) {
67-
_close(fd);
68-
return Name;
69-
}
70-
if (errno == EEXIST)
71-
continue;
72-
abort();
60+
while (true) {
61+
char Name[] = "libcxx.XXXXXX";
62+
if (_mktemp_s(Name, sizeof(Name)) != 0)
63+
abort();
64+
int fd = _open(Name, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
65+
if (fd != -1) {
66+
_close(fd);
67+
return Name;
7368
}
69+
if (errno == EEXIST)
70+
continue;
71+
abort();
72+
}
73+
#elif !__has_include(<unistd.h>)
74+
// Without `unistd.h` we cannot guarantee that the file is unused, however we
75+
// can simply generate a good guess in the temporary folder and create it.
76+
constexpr char chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
77+
char Name[] = "/tmp/libcxx.XXXXXX";
78+
for (std::size_t i = 0; i < sizeof(Name); ++i)
79+
if (Name[i] == 'X')
80+
Name[i] = chars[rand() % strlen(chars)];
81+
FILE* file = fopen(filename, "w");
82+
if (!file)
83+
abort();
84+
if (fclose(file) == EOF)
85+
abort();
86+
return std::string(Name);
7487
#else
75-
std::string Name = "libcxx.XXXXXX";
76-
int FD = mkstemp(&Name[0]);
77-
if (FD == -1) {
78-
perror("mkstemp");
79-
abort();
80-
}
81-
close(FD);
82-
return Name;
88+
std::string Name = "libcxx.XXXXXX";
89+
int FD = mkstemp(&Name[0]);
90+
if (FD == -1) {
91+
perror("mkstemp");
92+
abort();
93+
}
94+
close(FD);
95+
return Name;
8396
#endif
8497
}
8598

0 commit comments

Comments
 (0)