From: Pawel Bylica Date: Fri, 6 Nov 2015 23:44:23 +0000 (+0000) Subject: Revert r252366: [Support] Use GetTempDir to get the temporary dir path on Windows. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=6bd362c2d9d3e3284708ba5e55d8f3ccf7493313 Revert r252366: [Support] Use GetTempDir to get the temporary dir path on Windows. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252367 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index c787dc2a3f8..49910af55a7 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -773,22 +773,49 @@ bool home_directory(SmallVectorImpl &result) { return getKnownFolderPath(FOLDERID_Profile, result); } +static bool getTempDirEnvVar(const char *Var, SmallVectorImpl &Res) { + SmallVector NameUTF16; + if (windows::UTF8ToUTF16(Var, NameUTF16)) + return false; + + SmallVector Buf; + size_t Size = 1024; + do { + Buf.reserve(Size); + Size = + GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity()); + if (Size == 0) + return false; + + // Try again with larger buffer. + } while (Size > Buf.capacity()); + Buf.set_size(Size); + + if (windows::UTF16ToUTF8(Buf.data(), Size, Res)) + return false; + return true; +} + +static bool getTempDirEnvVar(SmallVectorImpl &Res) { + const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"}; + for (const char *Env : EnvironmentVariables) { + if (getTempDirEnvVar(Env, Res)) + return true; + } + return false; +} + void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl &Result) { (void)ErasedOnReboot; + Result.clear(); - wchar_t Path[MAX_PATH + 2]; // GetTempPath can return MAX_PATH + 1 + null - if (auto PathLength = ::GetTempPathW(sizeof(Path) / sizeof(wchar_t), Path)) { - assert(PathLength > 0 && PathLength <= (MAX_PATH + 1) && - "GetTempPath returned undocumented result"); - if (Path[PathLength - 1] == L'\\') - --PathLength; // skip trailing "\" added by GetTempPath - if (!UTF16ToUTF8(Path, PathLength, Result)) - return; - } + // Check whether the temporary directory is specified by an environment + // variable. + if (getTempDirEnvVar(Result)) + return; // Fall back to a system default. const char *DefaultResult = "C:\\TEMP"; - Result.clear(); Result.append(DefaultResult, DefaultResult + strlen(DefaultResult)); } } // end namespace path diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index ebfd266ebbe..a7a6a4add7c 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -351,76 +351,6 @@ TEST(Support, UserCacheDirectory) { } } -TEST(Support, TempDirectory) { - SmallString<32> TempDir; - path::system_temp_directory(false, TempDir); - EXPECT_TRUE(!TempDir.empty()); - TempDir.clear(); - path::system_temp_directory(true, TempDir); - EXPECT_TRUE(!TempDir.empty()); -} - -static std::string path2regex(std::string Path) { - size_t Pos = 0; - while ((Pos = Path.find('\\', Pos)) != std::string::npos) { - Path.replace(Pos, 1, "\\\\"); - Pos += 2; - } - return Path; -} - -/// Helper for running temp dir test in separated process. See below. -#define EXPECT_TEMP_DIR(prepare, expected) \ - EXPECT_EXIT( \ - { \ - prepare; \ - SmallString<300> TempDir; \ - path::system_temp_directory(true, TempDir); \ - raw_os_ostream(std::cerr) << TempDir; \ - std::exit(0); \ - }, \ - ::testing::ExitedWithCode(0), path2regex(expected)) - -#ifdef LLVM_ON_WIN32 -TEST(SupportDeathTest, TempDirectoryOnWindows) { - // In this test we want to check how system_temp_directory responds to - // different values of specific env vars. To prevent corrupting env vars of - // the current process all checks are done in separated processes. - EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:\\OtherFolder"), "C:\\OtherFolder"); - EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:/Unix/Path/Seperators"), - "C:\\Unix\\Path\\Seperators"); - EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"Local Path"), ".+\\Local Path$"); - EXPECT_TEMP_DIR( - _wputenv_s(L"TMP", L"C:\\2\x03C0r-\x00B5\x00B3\\\x2135\x2080"), - "C:\\2\xCF\x80r-\xC2\xB5\xC2\xB3\\\xE2\x84\xB5\xE2\x82\x80"); - - // Test $TMP empty, $TEMP set. - EXPECT_TEMP_DIR( - { - _wputenv_s(L"TMP", L""); - _wputenv_s(L"TEMP", L"C:\\Valid\\Path"); - }, - "C:\\Valid\\Path"); - - // Test evn var / path with 260 chars. - SmallString<270> Expected{"C:\\Temp\\AB\\123456789"}; - while (Expected.size() < 260) - Expected.append("\\DirNameWith19Charss"); - ASSERT_EQ(260, Expected.size()); - EXPECT_TEMP_DIR(_putenv_s("TMP", Expected.c_str()), Expected.c_str()); - - // Test evn var 261 chars. - Expected.append("X"); - ASSERT_EQ(261, Expected.size()); - EXPECT_TEMP_DIR( - { - _putenv_s("TMP", Expected.c_str()); - _wputenv_s(L"TEMP", L"C:\\Short\\Path"); - }, - "C:\\Short\\Path"); -} -#endif - class FileSystemTest : public testing::Test { protected: /// Unique temporary directory in which all created filesystem entities must