From a90e74510911aff36bba06d80dd216c8c89fd7ae Mon Sep 17 00:00:00 2001 From: Pawel Bylica Date: Tue, 17 Nov 2015 16:54:32 +0000 Subject: [Support] Tweak path::system_temp_directory() on Windows. Summary: This patch changes the behavior of path::system_temp_directory() on Windows to be closer to GetTempPath Windows API call. Enforces path separator to be the native one, makes path absolute, etc. GetTempPath is not used directly because of limitations/implementation bugs on Windows 7. Windows specific unit tests are added. Most of them runs in separated process with modified environment variables. This change fixes FileSystemTest.CreateDir unittest that had been failing when run from Unix-like shell on Windows (Unix-like path separator (/) used in env variables). Reviewers: chapuni, rafael, aaron.ballman Subscribers: rafael, llvm-commits Differential Revision: http://reviews.llvm.org/D14231 llvm-svn: 253345 --- llvm/lib/Support/Windows/Path.inc | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'llvm/lib/Support/Windows') diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 49910af55a7..4e4841231ef 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -773,17 +773,12 @@ 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; - +static bool getTempDirEnvVar(const wchar_t *Var, SmallVectorImpl &Res) { SmallVector Buf; size_t Size = 1024; do { Buf.reserve(Size); - Size = - GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity()); + Size = GetEnvironmentVariableW(Var, Buf.data(), Buf.capacity()); if (Size == 0) return false; @@ -791,14 +786,12 @@ static bool getTempDirEnvVar(const char *Var, SmallVectorImpl &Res) { } while (Size > Buf.capacity()); Buf.set_size(Size); - if (windows::UTF16ToUTF8(Buf.data(), Size, Res)) - return false; - return true; + return !windows::UTF16ToUTF8(Buf.data(), Size, Res); } static bool getTempDirEnvVar(SmallVectorImpl &Res) { - const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"}; - for (const char *Env : EnvironmentVariables) { + const wchar_t *EnvironmentVariables[] = {L"TMP", L"TEMP", L"USERPROFILE"}; + for (auto *Env : EnvironmentVariables) { if (getTempDirEnvVar(Env, Res)) return true; } @@ -809,13 +802,19 @@ void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl &Result) { (void)ErasedOnReboot; Result.clear(); - // Check whether the temporary directory is specified by an environment - // variable. - if (getTempDirEnvVar(Result)) + // Check whether the temporary directory is specified by an environment var. + // This matches GetTempPath logic to some degree. GetTempPath is not used + // directly as it cannot handle evn var longer than 130 chars on Windows 7 + // (fixed on Windows 8). + if (getTempDirEnvVar(Result)) { + assert(!Result.empty() && "Unexpected empty path"); + native(Result); // Some Unix-like shells use Unix path separator in $TMP. + fs::make_absolute(Result); // Make it absolute if not already. return; + } // Fall back to a system default. - const char *DefaultResult = "C:\\TEMP"; + const char *DefaultResult = "C:\\Temp"; Result.append(DefaultResult, DefaultResult + strlen(DefaultResult)); } } // end namespace path -- cgit v1.2.3