summaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-02-24 03:07:41 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-02-24 03:07:41 +0000
commit69aeeee4e1b58c76cdef06b3cbe0fcad2556b9a2 (patch)
tree749886ebe611d9c995103bef3d0574075e5c6f17 /lib/Support
parent6822655f561a62ebafd3ce35c62fefebcea5f1b1 (diff)
downloadllvm-69aeeee4e1b58c76cdef06b3cbe0fcad2556b9a2.tar.gz
llvm-69aeeee4e1b58c76cdef06b3cbe0fcad2556b9a2.tar.bz2
llvm-69aeeee4e1b58c76cdef06b3cbe0fcad2556b9a2.tar.xz
Share a createUniqueEntity implementation between unix and windows.
The only extra bit of functionality that had to be exposed for this be be implemented in Path.cpp is opening a file in rw mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202005 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/Path.cpp75
-rw-r--r--lib/Support/Unix/Path.inc77
-rw-r--r--lib/Support/Windows/Path.inc143
3 files changed, 90 insertions, 205 deletions
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index 535ff00bae..5b8be18db3 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -27,6 +27,8 @@
#include <io.h>
#endif
+using namespace llvm;
+
namespace {
using llvm::StringRef;
using llvm::sys::path::is_separator;
@@ -162,10 +164,75 @@ enum FSEntity {
};
// Implemented in Unix/Path.inc and Windows/Path.inc.
-static llvm::error_code
-createUniqueEntity(const llvm::Twine &Model, int &ResultFD,
- llvm::SmallVectorImpl<char> &ResultPath,
- bool MakeAbsolute, unsigned Mode, FSEntity Type);
+static error_code TempDir(SmallVectorImpl<char> &result);
+
+static error_code createUniqueEntity(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ bool MakeAbsolute, unsigned Mode,
+ FSEntity Type) {
+ SmallString<128> ModelStorage;
+ Model.toVector(ModelStorage);
+
+ if (MakeAbsolute) {
+ // Make model absolute by prepending a temp directory if it's not already.
+ if (!sys::path::is_absolute(Twine(ModelStorage))) {
+ SmallString<128> TDir;
+ if (error_code EC = TempDir(TDir))
+ return EC;
+ sys::path::append(TDir, Twine(ModelStorage));
+ ModelStorage.swap(TDir);
+ }
+ }
+
+ // From here on, DO NOT modify model. It may be needed if the randomly chosen
+ // path already exists.
+ ResultPath = ModelStorage;
+ // Null terminate.
+ 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 (error_code EC = sys::fs::openFileForWrite(
+ Twine(ResultPath.begin()), ResultFD,
+ sys::fs::F_RW | sys::fs::F_Excl | sys::fs::F_Binary, Mode)) {
+ if (EC == errc::file_exists)
+ goto retry_random_path;
+ return EC;
+ }
+
+ return error_code::success();
+ }
+
+ case FS_Name: {
+ bool Exists;
+ error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
+ if (EC)
+ return EC;
+ if (Exists)
+ goto retry_random_path;
+ return error_code::success();
+ }
+
+ case FS_Dir: {
+ if (error_code EC = sys::fs::create_directory(ResultPath.begin(), false)) {
+ if (EC == errc::file_exists)
+ goto retry_random_path;
+ return EC;
+ }
+ return error_code::success();
+ }
+ }
+ llvm_unreachable("Invalid Type");
+}
namespace llvm {
namespace sys {
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index e211ac9911..2249b64b45 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -103,76 +103,6 @@ static error_code TempDir(SmallVectorImpl<char> &result) {
return error_code::success();
}
-static error_code createUniqueEntity(const Twine &Model, int &ResultFD,
- SmallVectorImpl<char> &ResultPath,
- bool MakeAbsolute, unsigned Mode,
- FSEntity Type) {
- SmallString<128> ModelStorage;
- Model.toVector(ModelStorage);
-
- if (MakeAbsolute) {
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = sys::path::is_absolute(Twine(ModelStorage));
- if (!absolute) {
- SmallString<128> TDir;
- if (error_code ec = TempDir(TDir)) return ec;
- sys::path::append(TDir, Twine(ModelStorage));
- ModelStorage.swap(TDir);
- }
- }
-
- // From here on, DO NOT modify model. It may be needed if the randomly chosen
- // path already exists.
- ResultPath = ModelStorage;
- // Null terminate.
- 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: {
- int RandomFD = ::open(ResultPath.begin(), O_RDWR | O_CREAT | O_EXCL, Mode);
- if (RandomFD == -1) {
- int SavedErrno = errno;
- // If the file existed, try again, otherwise, error.
- if (SavedErrno == errc::file_exists)
- goto retry_random_path;
- return error_code(SavedErrno, system_category());
- }
-
- ResultFD = RandomFD;
- return error_code::success();
- }
-
- case FS_Name: {
- bool Exists;
- error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
- if (EC)
- return EC;
- if (Exists)
- goto retry_random_path;
- return error_code::success();
- }
-
- case FS_Dir: {
- if (error_code EC = sys::fs::create_directory(ResultPath.begin(), false)) {
- if (EC == errc::file_exists)
- goto retry_random_path;
- return EC;
- }
- return error_code::success();
- }
- }
- llvm_unreachable("Invalid Type");
-}
-
namespace llvm {
namespace sys {
namespace fs {
@@ -755,7 +685,12 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD,
assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
"Cannot specify both 'excl' and 'append' file creation flags!");
- int OpenFlags = O_WRONLY | O_CREAT;
+ int OpenFlags = O_CREAT;
+
+ if (Flags & F_RW)
+ OpenFlags |= O_RDWR;
+ else
+ OpenFlags |= O_WRONLY;
if (Flags & F_Append)
OpenFlags |= O_APPEND;
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc
index 2e33c129e3..a72d0bf0b1 100644
--- a/lib/Support/Windows/Path.inc
+++ b/lib/Support/Windows/Path.inc
@@ -44,20 +44,21 @@ using namespace llvm;
using llvm::sys::windows::UTF8ToUTF16;
using llvm::sys::windows::UTF16ToUTF8;
-static error_code TempDir(SmallVectorImpl<wchar_t> &result) {
+static error_code TempDir(SmallVectorImpl<char> &Result) {
+ SmallVector<wchar_t, 64> Res;
retry_temp_dir:
- DWORD len = ::GetTempPathW(result.capacity(), result.begin());
+ DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin());
- if (len == 0)
+ if (Len == 0)
return windows_error(::GetLastError());
- if (len > result.capacity()) {
- result.reserve(len);
+ if (Len > Res.capacity()) {
+ Res.reserve(Len);
goto retry_temp_dir;
}
- result.set_size(len);
- return error_code::success();
+ Res.set_size(Len);
+ return UTF16ToUTF8(Res.begin(), Res.size(), Result);
}
static bool is_separator(const wchar_t value) {
@@ -70,128 +71,6 @@ static bool is_separator(const wchar_t value) {
}
}
-// FIXME: mode should be used here and default to user r/w only,
-// it currently comes in as a UNIX mode.
-static error_code createUniqueEntity(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path,
- bool makeAbsolute, unsigned mode,
- FSEntity Type) {
- // Use result_path as temp storage.
- result_path.set_size(0);
- StringRef m = model.toStringRef(result_path);
-
- SmallVector<wchar_t, 128> model_utf16;
- if (error_code ec = UTF8ToUTF16(m, model_utf16)) return ec;
-
- if (makeAbsolute) {
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = sys::path::is_absolute(m);
-
- if (!absolute) {
- SmallVector<wchar_t, 64> temp_dir;
- if (error_code ec = TempDir(temp_dir)) return ec;
- // Handle c: by removing it.
- if (model_utf16.size() > 2 && model_utf16[1] == L':') {
- model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2);
- }
- model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end());
- }
- }
-
- // Replace '%' with random chars. From here on, DO NOT modify model. It may be
- // needed if the randomly chosen path already exists.
- SmallVector<wchar_t, 128> random_path_utf16;
-
-retry_random_path:
- random_path_utf16.set_size(0);
- for (SmallVectorImpl<wchar_t>::const_iterator i = model_utf16.begin(),
- e = model_utf16.end();
- i != e; ++i) {
- if (*i == L'%') {
- unsigned val = sys::Process::GetRandomNumber();
- random_path_utf16.push_back(L"0123456789abcdef"[val & 15]);
- }
- else
- random_path_utf16.push_back(*i);
- }
- // Make random_path_utf16 null terminated.
- random_path_utf16.push_back(0);
- random_path_utf16.pop_back();
-
- HANDLE TempFileHandle = INVALID_HANDLE_VALUE;
-
- switch (Type) {
- case FS_File: {
- // Try to create + open the path.
- TempFileHandle =
- ::CreateFileW(random_path_utf16.begin(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL,
- // Return ERROR_FILE_EXISTS if the file
- // already exists.
- CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL);
- if (TempFileHandle == INVALID_HANDLE_VALUE) {
- // If the file existed, try again, otherwise, error.
- error_code ec = windows_error(::GetLastError());
- if (ec == windows_error::file_exists)
- goto retry_random_path;
-
- return ec;
- }
-
- // Convert the Windows API file handle into a C-runtime handle.
- int fd = ::_open_osfhandle(intptr_t(TempFileHandle), 0);
- if (fd == -1) {
- ::CloseHandle(TempFileHandle);
- ::DeleteFileW(random_path_utf16.begin());
- // MSDN doesn't say anything about _open_osfhandle setting errno or
- // GetLastError(), so just return invalid_handle.
- return windows_error::invalid_handle;
- }
-
- result_fd = fd;
- break;
- }
-
- case FS_Name: {
- DWORD attributes = ::GetFileAttributesW(random_path_utf16.begin());
- if (attributes != INVALID_FILE_ATTRIBUTES)
- goto retry_random_path;
- error_code EC = make_error_code(windows_error(::GetLastError()));
- if (EC != windows_error::file_not_found &&
- EC != windows_error::path_not_found)
- return EC;
- break;
- }
-
- case FS_Dir:
- if (!::CreateDirectoryW(random_path_utf16.begin(), NULL)) {
- error_code EC = windows_error(::GetLastError());
- if (EC != windows_error::already_exists)
- return EC;
- goto retry_random_path;
- }
- break;
- }
-
- // Set result_path to the utf-8 representation of the path.
- if (error_code ec = UTF16ToUTF8(random_path_utf16.begin(),
- random_path_utf16.size(), result_path)) {
- switch (Type) {
- case FS_File:
- ::CloseHandle(TempFileHandle);
- ::DeleteFileW(random_path_utf16.begin());
- case FS_Name:
- break;
- case FS_Dir:
- ::RemoveDirectoryW(random_path_utf16.begin());
- break;
- }
- return ec;
- }
-
- return error_code::success();
-}
-
namespace llvm {
namespace sys {
namespace fs {
@@ -973,7 +852,11 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD,
else
CreationDisposition = CREATE_ALWAYS;
- HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_WRITE,
+ DWORD Access = GENERIC_WRITE;
+ if (Flags & F_RW)
+ Access |= GENERIC_READ;
+
+ HANDLE H = ::CreateFileW(PathUTF16.begin(), Access,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);