From 9be4884731b20e540b13b47737f0b4acb7c66e86 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 26 Aug 2014 14:47:52 +0000 Subject: [PATCH] Merge TempDir and system_temp_directory. We had two functions for finding the temp or cache directory. Each had a different set of smarts about OS specific APIs. With this patch system_temp_directory becomes the only way to do it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216460 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Path.cpp | 58 +-------------------------- lib/Support/Unix/Path.inc | 76 ++++++++++++++++++++++++++++-------- lib/Support/Windows/Path.inc | 62 +++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 90 deletions(-) diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp index 4d179218f78..259000b4e47 100644 --- a/lib/Support/Path.cpp +++ b/lib/Support/Path.cpp @@ -164,9 +164,6 @@ enum FSEntity { FS_Name }; -// Implemented in Unix/Path.inc and Windows/Path.inc. -static std::error_code TempDir(SmallVectorImpl &result); - static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl &ResultPath, bool MakeAbsolute, unsigned Mode, @@ -178,8 +175,7 @@ static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, // Make model absolute by prepending a temp directory if it's not already. if (!sys::path::is_absolute(Twine(ModelStorage))) { SmallString<128> TDir; - if (std::error_code EC = TempDir(TDir)) - return EC; + sys::path::system_temp_directory(true, TDir); sys::path::append(TDir, Twine(ModelStorage)); ModelStorage.swap(TDir); } @@ -602,58 +598,6 @@ const StringRef get_separator() { return preferred_separator_string; } -void system_temp_directory(bool erasedOnReboot, SmallVectorImpl &result) { - result.clear(); - -#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR) - // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR. - // macros defined in on darwin >= 9 - int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR - : _CS_DARWIN_USER_CACHE_DIR; - size_t ConfLen = confstr(ConfName, nullptr, 0); - if (ConfLen > 0) { - do { - result.resize(ConfLen); - ConfLen = confstr(ConfName, result.data(), result.size()); - } while (ConfLen > 0 && ConfLen != result.size()); - - if (ConfLen > 0) { - assert(result.back() == 0); - result.pop_back(); - return; - } - - result.clear(); - } -#endif - - // Check whether the temporary directory is specified by an environment - // variable. - const char *EnvironmentVariable; -#ifdef LLVM_ON_WIN32 - EnvironmentVariable = "TEMP"; -#else - EnvironmentVariable = "TMPDIR"; -#endif - if (char *RequestedDir = getenv(EnvironmentVariable)) { - result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); - return; - } - - // Fall back to a system default. - const char *DefaultResult; -#ifdef LLVM_ON_WIN32 - (void)erasedOnReboot; - DefaultResult = "C:\\TEMP"; -#else - if (erasedOnReboot) - DefaultResult = "/tmp"; - else - DefaultResult = "/var/tmp"; -#endif - result.append(DefaultResult, DefaultResult + strlen(DefaultResult)); -} - bool has_root_name(const Twine &path) { SmallString<128> path_storage; StringRef p = path.toStringRef(path_storage); diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index 64ea23c0689..24b0e21ce0a 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -87,22 +87,6 @@ namespace { }; } -static std::error_code TempDir(SmallVectorImpl &result) { - // FIXME: Don't use TMPDIR if program is SUID or SGID enabled. - const char *dir = nullptr; - (dir = std::getenv("TMPDIR")) || (dir = std::getenv("TMP")) || - (dir = std::getenv("TEMP")) || (dir = std::getenv("TEMPDIR")) || -#ifdef P_tmpdir - (dir = P_tmpdir) || -#endif - (dir = "/tmp"); - - result.clear(); - StringRef d(dir); - result.append(d.begin(), d.end()); - return std::error_code(); -} - namespace llvm { namespace sys { namespace fs { @@ -665,6 +649,66 @@ bool home_directory(SmallVectorImpl &result) { return false; } +static const char *getEnvTempDir() { + // Check whether the temporary directory is specified by an environment + // variable. + const char *EnvironmentVariables[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; + for (const char *Env : EnvironmentVariables) { + if (const char *Dir = std::getenv(Env)) + return Dir; + } + + return nullptr; +} + +static const char *getDefaultTempDir(bool ErasedOnReboot) { +#ifdef P_tmpdir + if (P_tmpdir) + return P_tmpdir; +#endif + + if (ErasedOnReboot) + return "/tmp"; + return "/var/tmp"; +} + +void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl &Result) { + Result.clear(); + + if (ErasedOnReboot) { + // There is no env variable for the cache directory. + if (const char *RequestedDir = getEnvTempDir()) { + Result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); + return; + } + } + +#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR) + // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR. + // macros defined in on darwin >= 9 + int ConfName = ErasedOnReboot? _CS_DARWIN_USER_TEMP_DIR + : _CS_DARWIN_USER_CACHE_DIR; + size_t ConfLen = confstr(ConfName, nullptr, 0); + if (ConfLen > 0) { + do { + Result.resize(ConfLen); + ConfLen = confstr(ConfName, Result.data(), Result.size()); + } while (ConfLen > 0 && ConfLen != Result.size()); + + if (ConfLen > 0) { + assert(Result.back() == 0); + Result.pop_back(); + return; + } + + Result.clear(); + } +#endif + + const char *RequestedDir = getDefaultTempDir(ErasedOnReboot); + Result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); +} + } // end namespace path } // end namespace sys diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index a57f252fbfc..b09c1989699 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -49,23 +49,6 @@ static std::error_code windows_error(DWORD E) { return mapWindowsError(E); } -static std::error_code TempDir(SmallVectorImpl &Result) { - SmallVector Res; -retry_temp_dir: - DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin()); - - if (Len == 0) - return windows_error(::GetLastError()); - - if (Len > Res.capacity()) { - Res.reserve(Len); - goto retry_temp_dir; - } - - Res.set_size(Len); - return UTF16ToUTF8(Res.begin(), Res.size(), Result); -} - static bool is_separator(const wchar_t value) { switch (value) { case L'\\': @@ -862,6 +845,51 @@ bool home_directory(SmallVectorImpl &result) { return true; } +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(); + + // 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.append(DefaultResult, DefaultResult + strlen(DefaultResult)); +} } // end namespace path namespace windows { -- 2.34.1