diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
commit | d9484dd61cc151c4f34c31e07f693fefa66316b5 (patch) | |
tree | ab0560b3da293f1fafd3269c59692e929418f5c2 /contrib/llvm/lib/Support/Path.cpp | |
parent | 79e0962d4c3cf1f0acf359a9d69cb3ac68c414c4 (diff) | |
parent | d8e91e46262bc44006913e6796843909f1ac7bcd (diff) |
Notes
Diffstat (limited to 'contrib/llvm/lib/Support/Path.cpp')
-rw-r--r-- | contrib/llvm/lib/Support/Path.cpp | 139 |
1 files changed, 68 insertions, 71 deletions
diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp index 768a819c8d05..5ce2f50ebdaa 100644 --- a/contrib/llvm/lib/Support/Path.cpp +++ b/contrib/llvm/lib/Support/Path.cpp @@ -190,48 +190,57 @@ createUniqueEntity(const Twine &Model, int &ResultFD, ResultPath.push_back(0); ResultPath.pop_back(); -retry_random_path: - // Replace '%' with random chars. - for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) { - if (ModelStorage[i] == '%') - ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15]; - } - - // Try to open + create the file. - switch (Type) { - case FS_File: { - if (std::error_code EC = - sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD, - sys::fs::CD_CreateNew, Flags, Mode)) { - if (EC == errc::file_exists) - goto retry_random_path; - return EC; + // Limit the number of attempts we make, so that we don't infinite loop. E.g. + // "permission denied" could be for a specific file (so we retry with a + // different name) or for the whole directory (retry would always fail). + // Checking which is racy, so we try a number of times, then give up. + std::error_code EC; + for (int Retries = 128; Retries > 0; --Retries) { + // Replace '%' with random chars. + for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) { + if (ModelStorage[i] == '%') + ResultPath[i] = + "0123456789abcdef"[sys::Process::GetRandomNumber() & 15]; } - return std::error_code(); - } + // Try to open + create the file. + switch (Type) { + case FS_File: { + EC = sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD, + sys::fs::CD_CreateNew, Flags, Mode); + if (EC) { + // errc::permission_denied happens on Windows when we try to open a file + // that has been marked for deletion. + if (EC == errc::file_exists || EC == errc::permission_denied) + continue; + return EC; + } - case FS_Name: { - std::error_code EC = - sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist); - if (EC == errc::no_such_file_or_directory) return std::error_code(); - if (EC) - return EC; - goto retry_random_path; - } + } - case FS_Dir: { - if (std::error_code EC = - sys::fs::create_directory(ResultPath.begin(), false)) { - if (EC == errc::file_exists) - goto retry_random_path; - return EC; + case FS_Name: { + EC = sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist); + if (EC == errc::no_such_file_or_directory) + return std::error_code(); + if (EC) + return EC; + continue; } - return std::error_code(); - } + + case FS_Dir: { + EC = sys::fs::create_directory(ResultPath.begin(), false); + if (EC) { + if (EC == errc::file_exists) + continue; + return EC; + } + return std::error_code(); + } + } + llvm_unreachable("Invalid Type"); } - llvm_unreachable("Invalid Type"); + return EC; } namespace llvm { @@ -524,7 +533,7 @@ void replace_path_prefix(SmallVectorImpl<char> &Path, // If prefixes have the same size we can simply copy the new one over. if (OldPrefix.size() == NewPrefix.size()) { - std::copy(NewPrefix.begin(), NewPrefix.end(), Path.begin()); + llvm::copy(NewPrefix, Path.begin()); return; } @@ -840,9 +849,8 @@ getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name); } -static std::error_code make_absolute(const Twine ¤t_directory, - SmallVectorImpl<char> &path, - bool use_current_directory) { +void make_absolute(const Twine ¤t_directory, + SmallVectorImpl<char> &path) { StringRef p(path.data(), path.size()); bool rootDirectory = path::has_root_directory(p); @@ -851,14 +859,11 @@ static std::error_code make_absolute(const Twine ¤t_directory, // Already absolute. if (rootName && rootDirectory) - return std::error_code(); + return; // All of the following conditions will need the current directory. SmallString<128> current_dir; - if (use_current_directory) - current_directory.toVector(current_dir); - else if (std::error_code ec = current_path(current_dir)) - return ec; + current_directory.toVector(current_dir); // Relative path. Prepend the current directory. if (!rootName && !rootDirectory) { @@ -866,7 +871,7 @@ static std::error_code make_absolute(const Twine ¤t_directory, path::append(current_dir, p); // Set path to the result. path.swap(current_dir); - return std::error_code(); + return; } if (!rootName && rootDirectory) { @@ -875,7 +880,7 @@ static std::error_code make_absolute(const Twine ¤t_directory, path::append(curDirRootName, p); // Set path to the result. path.swap(curDirRootName); - return std::error_code(); + return; } if (rootName && !rootDirectory) { @@ -887,20 +892,23 @@ static std::error_code make_absolute(const Twine ¤t_directory, SmallString<128> res; path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath); path.swap(res); - return std::error_code(); + return; } llvm_unreachable("All rootName and rootDirectory combinations should have " "occurred above!"); } -std::error_code make_absolute(const Twine ¤t_directory, - SmallVectorImpl<char> &path) { - return make_absolute(current_directory, path, true); -} - std::error_code make_absolute(SmallVectorImpl<char> &path) { - return make_absolute(Twine(), path, false); + if (path::is_absolute(path)) + return {}; + + SmallString<128> current_dir; + if (std::error_code ec = current_path(current_dir)) + return ec; + + make_absolute(current_dir, path); + return {}; } std::error_code create_directories(const Twine &Path, bool IgnoreExisting, @@ -1076,12 +1084,13 @@ std::error_code is_other(const Twine &Path, bool &Result) { return std::error_code(); } -void directory_entry::replace_filename(const Twine &filename, - basic_file_status st) { - SmallString<128> path = path::parent_path(Path); - path::append(path, filename); - Path = path.str(); - Status = st; +void directory_entry::replace_filename(const Twine &Filename, file_type Type, + basic_file_status Status) { + SmallString<128> PathStr = path::parent_path(Path); + path::append(PathStr, Filename); + this->Path = PathStr.str(); + this->Type = Type; + this->Status = Status; } ErrorOr<perms> getPermissions(const Twine &Path) { @@ -1230,17 +1239,5 @@ Expected<TempFile> TempFile::create(const Twine &Model, unsigned Mode) { } } -namespace path { - -bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1, - const Twine &Path2, const Twine &Path3) { - if (getUserCacheDir(Result)) { - append(Result, Path1, Path2, Path3); - return true; - } - return false; -} - -} // end namespace path } // end namsspace sys } // end namespace llvm |