aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar laszlocsomor <laszlocsomor@google.com>2017-07-21 13:18:13 +0200
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-07-24 09:51:01 +0200
commitb69acfaa1c281ac2e8fd7450f07bb3735d24ae23 (patch)
treebc6eb5f65d44fc8a29bcaba197f1e87ba7ab1a1a
parent1920dd98491fdb00daf6187beed58c8ff06d4fd6 (diff)
Windows: add blaze_util::AsAbsoluteWindowsPath
Replace blaze_util::AsWindowsPathWithUncPrefix with AsAbsoluteWindowsPath, which always returns an absolute path. Fixes https://github.com/bazelbuild/bazel/issues/2935 RELNOTES: none PiperOrigin-RevId: 162727218
-rw-r--r--src/main/cpp/blaze_util_windows.cc26
-rw-r--r--src/main/cpp/util/file_platform.h6
-rw-r--r--src/main/cpp/util/file_windows.cc92
-rw-r--r--src/test/cpp/util/file_windows_test.cc26
-rw-r--r--third_party/ijar/mapped_file_windows.cc10
-rw-r--r--third_party/ijar/platform_utils.cc4
6 files changed, 95 insertions, 69 deletions
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index 15981525f8..dce52d5ad0 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -684,9 +684,9 @@ void ExecuteDaemon(const string& exe, const std::vector<string>& args_vector,
#endif // not COMPILER_MSVC
wstring wdaemon_output;
- if (!blaze_util::AsWindowsPathWithUncPrefix(daemon_output, &wdaemon_output)) {
+ if (!blaze_util::AsAbsoluteWindowsPath(daemon_output, &wdaemon_output)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "ExecuteDaemon(%s): AsWindowsPathWithUncPrefix(%s)", exe.c_str(),
+ "ExecuteDaemon(%s): AsAbsoluteWindowsPath(%s)", exe.c_str(),
daemon_output.c_str());
}
@@ -932,12 +932,14 @@ string ConvertPath(const string& path) {
#ifdef COMPILER_MSVC
// The path may not be Windows-style and may not be normalized, so convert it.
wstring wpath;
- if (!blaze_util::AsWindowsPathWithUncPrefix(path, &wpath)) {
- pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "ConvertPath(%s)",
- path.c_str());
+ if (!blaze_util::AsAbsoluteWindowsPath(path, &wpath)) {
+ pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
+ "ConvertPath(%s): AsAbsoluteWindowsPath", path.c_str());
}
std::transform(wpath.begin(), wpath.end(), wpath.begin(), ::towlower);
- return string(blaze_util::WstringToCstring(wpath.c_str()).get());
+ return string(blaze_util::WstringToCstring(
+ blaze_util::RemoveUncPrefixMaybe(wpath.c_str()))
+ .get());
#else // not COMPILER_MSVC
// If the path looks like %USERPROFILE%/foo/bar, don't convert.
if (path.empty() || path[0] == '%') {
@@ -977,15 +979,15 @@ string ConvertPathList(const string& path_list) {
bool SymlinkDirectories(const string &posix_target, const string &posix_name) {
wstring name;
wstring target;
- if (!blaze_util::AsWindowsPathWithUncPrefix(posix_name, &name)) {
+ if (!blaze_util::AsAbsoluteWindowsPath(posix_name, &name)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "SymlinkDirectories(%s, %s): AsWindowsPathWithUncPrefix(%s)",
+ "SymlinkDirectories(%s, %s): AsAbsoluteWindowsPath(%s)",
posix_target.c_str(), posix_name.c_str(), posix_target.c_str());
return false;
}
- if (!blaze_util::AsWindowsPathWithUncPrefix(posix_target, &target)) {
+ if (!blaze_util::AsAbsoluteWindowsPath(posix_target, &target)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "SymlinkDirectories(%s, %s): AsWindowsPathWithUncPrefix(%s)",
+ "SymlinkDirectories(%s, %s): AsAbsoluteWindowsPath(%s)",
posix_target.c_str(), posix_name.c_str(), posix_name.c_str());
return false;
}
@@ -1277,9 +1279,9 @@ uint64_t AcquireLock(const string& output_base, bool batch_mode, bool block,
BlazeLock* blaze_lock) {
string lockfile = blaze_util::JoinPath(output_base, "lock");
wstring wlockfile;
- if (!blaze_util::AsWindowsPathWithUncPrefix(lockfile, &wlockfile)) {
+ if (!blaze_util::AsAbsoluteWindowsPath(lockfile, &wlockfile)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "AcquireLock(%s): AsWindowsPathWithUncPrefix(%s)", output_base.c_str(),
+ "AcquireLock(%s): AsAbsoluteWindowsPath(%s)", output_base.c_str(),
lockfile.c_str());
}
diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h
index 179eac368d..db217f2dee 100644
--- a/src/main/cpp/util/file_platform.h
+++ b/src/main/cpp/util/file_platform.h
@@ -209,9 +209,9 @@ void ForEachDirectoryEntry(const std::string &path,
DirectoryEntryConsumer *consume);
#if defined(COMPILER_MSVC) || defined(__CYGWIN__)
-// Like `AsWindowsPath` but the result is absolute and has UNC prefix if needed.
-bool AsWindowsPathWithUncPrefix(const std::string &path, std::wstring *wpath,
- size_t max_path = 260 /* MAX_PATH */);
+const wchar_t *RemoveUncPrefixMaybe(const wchar_t *ptr);
+
+bool AsAbsoluteWindowsPath(const std::string &path, std::wstring *wpath);
// Same as `AsWindowsPath`, but returns a lowercase 8dot3 style shortened path.
// Result will never have a UNC prefix, nor a trailing "/" or "\".
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index fb6eca39c0..ca1ff548b3 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -112,7 +112,7 @@ static void AddUncPrefixMaybe(wstring* path, size_t max_path = MAX_PATH) {
}
}
-static const wchar_t* RemoveUncPrefixMaybe(const wchar_t* ptr) {
+const wchar_t* RemoveUncPrefixMaybe(const wchar_t* ptr) {
return ptr + (HasUncPrefix(ptr) ? 4 : 0);
}
@@ -184,10 +184,9 @@ bool WindowsFileMtime::GetIfInDistantFuture(const string& path, bool* result) {
return true;
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "WindowsFileMtime::GetIfInDistantFuture(%s): "
- "AsWindowsPathWithUncPrefix",
+ "WindowsFileMtime::GetIfInDistantFuture(%s): AsAbsoluteWindowsPath",
path.c_str());
}
@@ -237,9 +236,9 @@ bool WindowsFileMtime::Set(const string& path, const FILETIME& time) {
return false;
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "WindowsFileMtime::Set(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "WindowsFileMtime::Set(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
@@ -515,20 +514,24 @@ bool AsWindowsPath(const string& path, wstring* result) {
return true;
}
-bool AsWindowsPathWithUncPrefix(const string& path, wstring* wpath,
- size_t max_path) {
+bool AsAbsoluteWindowsPath(const string& path, wstring* result) {
+ if (path.empty()) {
+ result->clear();
+ return true;
+ }
if (IsDevNull(path)) {
- wpath->assign(L"NUL");
+ result->assign(L"NUL");
return true;
}
-
- if (!AsWindowsPath(path, wpath)) {
+ if (!AsWindowsPath(path, result)) {
return false;
}
- if (!IsAbsolute(path)) {
- wpath->assign(wstring(GetCwdW().get()) + L"\\" + *wpath);
+ if (!IsRootOrAbsolute(*result, /* must_be_root */ false)) {
+ *result = wstring(GetCwdW().get()) + L"\\" + *result;
+ }
+ if (!HasUncPrefix(result->c_str())) {
+ *result = wstring(L"\\\\?\\") + *result;
}
- AddUncPrefixMaybe(wpath, max_path);
return true;
}
@@ -541,9 +544,9 @@ bool AsShortWindowsPath(const string& path, string* result) {
result->clear();
wstring wpath;
wstring wsuffix;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "AsShortWindowsPath(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "AsShortWindowsPath(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
DWORD size = ::GetShortPathNameW(wpath.c_str(), nullptr, 0);
@@ -605,10 +608,9 @@ static bool OpenFileForReading(const string& filename, HANDLE* result) {
return true;
}
wstring wfilename;
- if (!AsWindowsPathWithUncPrefix(filename, &wfilename)) {
+ if (!AsAbsoluteWindowsPath(filename, &wfilename)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "OpenFileForReading(%s): AsWindowsPathWithUncPrefix",
- filename.c_str());
+ "OpenFileForReading(%s): AsAbsoluteWindowsPath", filename.c_str());
}
*result = ::CreateFileW(
/* lpFileName */ wfilename.c_str(),
@@ -675,9 +677,9 @@ bool WriteFile(const void* data, size_t size, const string& filename,
return true; // mimic write(2) behavior with /dev/null
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(filename, &wpath)) {
+ if (!AsAbsoluteWindowsPath(filename, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "WriteFile(%s): AsWindowsPathWithUncPrefix", filename.c_str());
+ "WriteFile(%s): AsAbsoluteWindowsPath", filename.c_str());
return false;
}
@@ -717,18 +719,18 @@ int WriteToStdOutErr(const void* data, size_t size, bool to_stdout) {
int RenameDirectory(const std::string& old_name, const std::string& new_name) {
wstring wold_name;
- if (!AsWindowsPathWithUncPrefix(old_name, &wold_name)) {
+ if (!AsAbsoluteWindowsPath(old_name, &wold_name)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "RenameDirectory(%s, %s): AsWindowsPathWithUncPrefix(%s)",
- old_name.c_str(), new_name.c_str(), old_name.c_str());
+ "RenameDirectory(%s, %s): AsAbsoluteWindowsPath(%s)", old_name.c_str(),
+ new_name.c_str(), old_name.c_str());
return kRenameDirectoryFailureOtherError;
}
wstring wnew_name;
- if (!AsWindowsPathWithUncPrefix(new_name, &wnew_name)) {
+ if (!AsAbsoluteWindowsPath(new_name, &wnew_name)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "RenameDirectory(%s, %s): AsWindowsPathWithUncPrefix(%s)",
- old_name.c_str(), new_name.c_str(), new_name.c_str());
+ "RenameDirectory(%s, %s): AsAbsoluteWindowsPath(%s)", old_name.c_str(),
+ new_name.c_str(), new_name.c_str());
return kRenameDirectoryFailureOtherError;
}
@@ -767,9 +769,9 @@ bool UnlinkPath(const string& file_path) {
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(file_path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(file_path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "UnlinkPath(%s): AsWindowsPathWithUncPrefix", file_path.c_str());
+ "UnlinkPath(%s): AsAbsoluteWindowsPath", file_path.c_str());
return false;
}
return UnlinkPathW(wpath);
@@ -899,9 +901,9 @@ bool JunctionResolver::Resolve(const WCHAR* path, unique_ptr<WCHAR[]>* result) {
bool ReadDirectorySymlink(const string& name, string* result) {
wstring wname;
- if (!AsWindowsPathWithUncPrefix(name, &wname)) {
+ if (!AsAbsoluteWindowsPath(name, &wname)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "ReadDirectorySymlink(%s): AsWindowsPathWithUncPrefix", name.c_str());
+ "ReadDirectorySymlink(%s): AsAbsoluteWindowsPath", name.c_str());
return false;
}
unique_ptr<WCHAR[]> result_ptr;
@@ -920,9 +922,9 @@ bool PathExists(const string& path) {
return true;
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "PathExists(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "PathExists(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
return JunctionResolver().Resolve(wpath.c_str(), nullptr);
@@ -936,9 +938,9 @@ string MakeCanonical(const char* path) {
if (path == nullptr || path[0] == 0) {
return "";
}
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "MakeCanonical(%s): AsWindowsPathWithUncPrefix", path);
+ "MakeCanonical(%s): AsAbsoluteWindowsPath", path);
}
// Resolve all segments of the path. Do this from leaf to root, so we always
@@ -1039,9 +1041,9 @@ static bool CanReadFileW(const wstring& path) {
bool CanReadFile(const std::string& path) {
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "CanReadFile(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "CanReadFile(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
return CanReadFileW(wpath);
@@ -1049,9 +1051,9 @@ bool CanReadFile(const std::string& path) {
bool CanExecuteFile(const std::string& path) {
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "CanExecuteFile(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "CanExecuteFile(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
return CanReadFileW(wpath) && (ends_with(wpath, wstring(L".exe")) ||
@@ -1062,9 +1064,9 @@ bool CanExecuteFile(const std::string& path) {
bool CanAccessDirectory(const std::string& path) {
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "CanAccessDirectory(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "CanAccessDirectory(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
DWORD attr = ::GetFileAttributesW(wpath.c_str());
@@ -1125,9 +1127,9 @@ bool IsDirectory(const string& path) {
return false;
}
wstring wpath;
- if (!AsWindowsPathWithUncPrefix(path, &wpath)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "IsDirectory(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "IsDirectory(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
return IsDirectoryW(wpath);
@@ -1176,9 +1178,9 @@ bool MakeDirectories(const string& path, unsigned int mode) {
wstring wpath;
// According to MSDN, CreateDirectory's limit without the UNC prefix is
// 248 characters (so it could fit another filename before reaching MAX_PATH).
- if (!AsWindowsPathWithUncPrefix(path, &wpath, 248)) {
+ if (!AsAbsoluteWindowsPath(path, &wpath)) {
pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
- "MakeDirectories(%s): AsWindowsPathWithUncPrefix", path.c_str());
+ "MakeDirectories(%s): AsAbsoluteWindowsPath", path.c_str());
return false;
}
return MakeDirectoriesW(wpath);
diff --git a/src/test/cpp/util/file_windows_test.cc b/src/test/cpp/util/file_windows_test.cc
index cab1947ba4..496c24d02f 100644
--- a/src/test/cpp/util/file_windows_test.cc
+++ b/src/test/cpp/util/file_windows_test.cc
@@ -23,6 +23,7 @@
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/native/windows/file.h"
+#include "src/main/native/windows/util.h"
#include "src/test/cpp/util/test_util.h"
#include "src/test/cpp/util/windows_test_util.h"
@@ -244,6 +245,29 @@ TEST_F(FileWindowsTest, TestAsWindowsPath) {
ASSERT_EQ(wlongpath, actual);
}
+TEST_F(FileWindowsTest, TestAsAbsoluteWindowsPath) {
+ SetEnvironmentVariableA("BAZEL_SH", "c:\\some\\long/path\\bin\\bash.exe");
+ ResetMsysRootForTesting();
+ wstring actual;
+
+ ASSERT_TRUE(AsAbsoluteWindowsPath("c:/", &actual));
+ ASSERT_EQ(L"\\\\?\\c:\\", actual);
+
+ ASSERT_TRUE(AsAbsoluteWindowsPath("c:/..\\non-existent//", &actual));
+ ASSERT_EQ(L"\\\\?\\c:\\non-existent", actual);
+
+ WCHAR cwd[MAX_PATH];
+ ASSERT_TRUE(::GetCurrentDirectoryW(MAX_PATH, cwd));
+ ASSERT_FALSE(bazel::windows::HasUncPrefix(cwd));
+ wstring cwdw(cwd);
+ ASSERT_EQ(cwdw.find_first_of(L'/'), wstring::npos);
+ wstring expected =
+ wstring(L"\\\\?\\") + cwdw +
+ ((cwdw.back() == L'\\') ? L"non-existent" : L"\\non-existent");
+ ASSERT_TRUE(AsAbsoluteWindowsPath("non-existent", &actual));
+ ASSERT_EQ(expected, actual);
+}
+
TEST_F(FileWindowsTest, TestAsShortWindowsPath) {
string actual;
ASSERT_TRUE(AsShortWindowsPath("/dev/null", &actual));
@@ -516,7 +540,7 @@ TEST_F(FileWindowsTest, TestMakeCanonical) {
// Create a dummy file: $TEST_TMPDIR/directory/subdirectory/foo.txt
string foo(JoinPath(dir2, "foo.txt"));
wstring wfoo;
- EXPECT_TRUE(AsWindowsPathWithUncPrefix(foo, &wfoo));
+ EXPECT_TRUE(AsAbsoluteWindowsPath(foo, &wfoo));
EXPECT_TRUE(CreateDummyFile(wfoo));
EXPECT_TRUE(CanReadFile(foo));
// Create junctions next to directory and subdirectory, pointing to them.
diff --git a/third_party/ijar/mapped_file_windows.cc b/third_party/ijar/mapped_file_windows.cc
index 253065e453..abc93c2791 100644
--- a/third_party/ijar/mapped_file_windows.cc
+++ b/third_party/ijar/mapped_file_windows.cc
@@ -45,9 +45,8 @@ MappedInputFile::MappedInputFile(const char* name) {
errmsg_ = errmsg;
wstring wname;
- if (!blaze_util::AsWindowsPathWithUncPrefix(name, &wname)) {
- blaze_util::pdie(255, "MappedInputFile(%s): AsWindowsPathWithUncPrefix",
- name);
+ if (!blaze_util::AsAbsoluteWindowsPath(name, &wname)) {
+ blaze_util::pdie(255, "MappedInputFile(%s): AsAbsoluteWindowsPath", name);
}
HANDLE file = CreateFileW(wname.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
@@ -120,9 +119,8 @@ MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) {
errmsg_ = errmsg;
wstring wname;
- if (!blaze_util::AsWindowsPathWithUncPrefix(name, &wname)) {
- blaze_util::pdie(255, "MappedOutputFile(%s): AsWindowsPathWithUncPrefix",
- name);
+ if (!blaze_util::AsAbsoluteWindowsPath(name, &wname)) {
+ blaze_util::pdie(255, "MappedOutputFile(%s): AsAbsoluteWindowsPath", name);
}
HANDLE file = CreateFileW(wname.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, 0, NULL);
diff --git a/third_party/ijar/platform_utils.cc b/third_party/ijar/platform_utils.cc
index a998cabc8e..dde8868005 100644
--- a/third_party/ijar/platform_utils.cc
+++ b/third_party/ijar/platform_utils.cc
@@ -38,8 +38,8 @@ using std::string;
bool stat_file(const char* path, Stat* result) {
#if defined(COMPILER_MSVC) || defined(__CYGWIN__)
std::wstring wpath;
- if (!blaze_util::AsWindowsPathWithUncPrefix(path, &wpath)) {
- blaze_util::pdie(255, "stat_file: AsWindowsPathWithUncPrefix(%s)", path);
+ if (!blaze_util::AsAbsoluteWindowsPath(path, &wpath)) {
+ blaze_util::pdie(255, "stat_file: AsAbsoluteWindowsPath(%s)", path);
}
bool success = false;
BY_HANDLE_FILE_INFORMATION info;