aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support/Path.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/Path.cpp')
-rw-r--r--contrib/llvm/lib/Support/Path.cpp139
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 &current_directory,
- SmallVectorImpl<char> &path,
- bool use_current_directory) {
+void make_absolute(const Twine &current_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 &current_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 &current_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 &current_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 &current_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 &current_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