diff options
author | 2017-03-30 12:38:05 +0000 | |
---|---|---|
committer | 2017-03-31 17:07:37 +0200 | |
commit | 111b3ac7ef616664890b733f7a0205adf40d3268 (patch) | |
tree | 2ae692178531f681c0a47ca0fc6705ec74959e5f /src | |
parent | 6127358c1799d8d83cebbd499edac89f869df41b (diff) |
Bazel client: simplify ReadDirectorySymlink
This is a bugfixed version of
https://cr.bazel.build/9520 which broke some
Google-internal tests.
This change allows removing duplicate code:
ReadDirectorySymlink was implemented on Windows as
a junction resolver, which is also implemented in
file_windows.cc. Now it uses the JunctionResolver.
RELNOTES: none
PiperOrigin-RevId: 151691895
Diffstat (limited to 'src')
-rw-r--r-- | src/main/cpp/blaze.cc | 3 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_platform.h | 5 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_posix.cc | 12 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_windows.cc | 92 | ||||
-rw-r--r-- | src/main/cpp/util/file_platform.h | 5 | ||||
-rw-r--r-- | src/main/cpp/util/file_posix.cc | 12 | ||||
-rw-r--r-- | src/main/cpp/util/file_windows.cc | 15 |
7 files changed, 34 insertions, 110 deletions
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 1457587faf..30692dabb8 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -1065,7 +1065,8 @@ static void EnsureCorrectRunningVersion(BlazeServer *server) { string installation_path = blaze_util::JoinPath(globals->options->output_base, "install"); string prev_installation; - bool ok = ReadDirectorySymlink(installation_path, &prev_installation); + bool ok = + blaze_util::ReadDirectorySymlink(installation_path, &prev_installation); if (!ok || !CompareAbsolutePaths(prev_installation, globals->options->install_base)) { if (server->Connected()) { diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h index f158b58a30..afb8c2d607 100644 --- a/src/main/cpp/blaze_util_platform.h +++ b/src/main/cpp/blaze_util_platform.h @@ -143,11 +143,6 @@ std::string ListSeparator(); // Implemented via junctions on Windows. bool SymlinkDirectories(const std::string& target, const std::string& link); -// Reads which directory a symlink points to. Puts the target of the symlink -// in ``result`` and returns if the operation was successful. Will not work on -// symlinks that don't point to directories on Windows. -bool ReadDirectorySymlink(const std::string& symlink, std::string* result); - // Compares two absolute paths. Necessary because the same path can have // multiple different names under msys2: "C:\foo\bar" or "C:/foo/bar" // (Windows-style) and "/c/foo/bar" (msys2 style). Returns if the paths are diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc index dab5f0ab64..67d52fec6b 100644 --- a/src/main/cpp/blaze_util_posix.cc +++ b/src/main/cpp/blaze_util_posix.cc @@ -345,18 +345,6 @@ string GetJvmVersion(const string& java_exe) { return ReadJvmVersion(version_string); } -bool ReadDirectorySymlink(const string &name, string* result) { - char buf[PATH_MAX + 1]; - int len = readlink(name.c_str(), buf, PATH_MAX); - if (len < 0) { - return false; - } - - buf[len] = 0; - *result = buf; - return true; -} - bool CompareAbsolutePaths(const string& a, const string& b) { return a == b; } diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc index 8e1d32907e..9eb11d739b 100644 --- a/src/main/cpp/blaze_util_windows.cc +++ b/src/main/cpp/blaze_util_windows.cc @@ -964,35 +964,6 @@ string ConvertPathList(const string& path_list) { #endif // COMPILER_MSVC } -static string ConvertPathToPosix(const string& win_path) { -#ifdef COMPILER_MSVC - // TODO(bazel-team) 2016-11-18: verify that this function is not needed on - // Windows. - return win_path; -#else // not COMPILER_MSVC - char* posix_path = static_cast<char*>(cygwin_create_path( - CCP_WIN_A_TO_POSIX, static_cast<const void*>(win_path.c_str()))); - string result(posix_path); - free(posix_path); - return result; -#endif // COMPILER_MSVC -} - -// Cribbed from ntifs.h, not present in windows.h - -#define REPARSE_MOUNTPOINT_HEADER_SIZE 8 - -typedef struct { - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[ANYSIZE_ARRAY]; -} REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER; - bool SymlinkDirectories(const string &posix_target, const string &posix_name) { wstring name; wstring target; @@ -1015,69 +986,6 @@ bool SymlinkDirectories(const string &posix_target, const string &posix_name) { return true; } -// TODO(laszlocsomor): use JunctionResolver in file_windows.cc -bool ReadDirectorySymlink(const string &posix_name, string* result) { - string name = ConvertPath(posix_name); - wstring wname; - - if (!blaze_util::AsWindowsPathWithUncPrefix(name, &wname)) { - PrintError("ReadDirectorySymlink: AsWindowsPathWithUncPrefix(" + name + - ")"); - return false; - } - - HANDLE directory = windows_util::OpenDirectory(wname.c_str(), false); - if (directory == INVALID_HANDLE_VALUE) { - return false; - } - - char reparse_buffer_bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_MOUNTPOINT_DATA_BUFFER* reparse_buffer = - reinterpret_cast<REPARSE_MOUNTPOINT_DATA_BUFFER *>(reparse_buffer_bytes); - memset(reparse_buffer_bytes, 0, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - - reparse_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - DWORD bytes_returned; - bool ok = ::DeviceIoControl( - directory, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - reparse_buffer, - MAXIMUM_REPARSE_DATA_BUFFER_SIZE, - &bytes_returned, - NULL); - if (!ok) { - PrintError("DeviceIoControl(FSCTL_GET_REPARSE_POINT, " + name + ")"); - } - - CloseHandle(directory); - if (!ok) { - return false; - } - - std::vector<char> print_name(reparse_buffer->PrintNameLength * sizeof(WCHAR) + - 1); - int count = ::WideCharToMultiByte( - CP_UTF8, - 0, - reparse_buffer->PathBuffer + - (reparse_buffer->PrintNameOffset / sizeof(WCHAR)), - reparse_buffer->PrintNameLength, - &print_name[0], - print_name.size(), - NULL, - NULL); - if (count == 0) { - PrintError("WideCharToMultiByte()"); - *result = ""; - return false; - } else { - *result = ConvertPathToPosix(&print_name[0]); - return true; - } -} - bool CompareAbsolutePaths(const string& a, const string& b) { return ConvertPath(a) == ConvertPath(b); } diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h index 50b75de3bb..31a0d1c24c 100644 --- a/src/main/cpp/util/file_platform.h +++ b/src/main/cpp/util/file_platform.h @@ -130,6 +130,11 @@ enum RenameDirectoryResult { // Returns one of the RenameDirectoryResult enum values. int RenameDirectory(const std::string &old_name, const std::string &new_name); +// Reads which directory a symlink points to. Puts the target of the symlink +// in ``result`` and returns if the operation was successful. Will not work on +// symlinks that don't point to directories on Windows. +bool ReadDirectorySymlink(const std::string &symlink, std::string *result); + // Unlinks the file given by 'file_path'. // Returns true on success. In case of failure sets errno. bool UnlinkPath(const std::string &file_path); diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index 076bff2bfd..daa465af94 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc @@ -251,6 +251,18 @@ int RenameDirectory(const std::string &old_name, const std::string &new_name) { } } +bool ReadDirectorySymlink(const string &name, string *result) { + char buf[PATH_MAX + 1]; + int len = readlink(name.c_str(), buf, PATH_MAX); + if (len < 0) { + return false; + } + + buf[len] = 0; + *result = buf; + return true; +} + bool UnlinkPath(const string &file_path) { return unlink(file_path.c_str()) == 0; } diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index c2e0fd79ee..af6ed4f325 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc @@ -863,6 +863,21 @@ bool JunctionResolver::Resolve(const WCHAR* path, unique_ptr<WCHAR[]>* result) { return Resolve(path, result, kMaximumJunctionDepth); } +bool ReadDirectorySymlink(const string& name, string* result) { + wstring wname; + if (!AsWindowsPathWithUncPrefix(name, &wname)) { + PrintError("ReadDirectorySymlink: AsWindowsPathWithUncPrefix(%s)", + name.c_str()); + return false; + } + unique_ptr<WCHAR[]> result_ptr; + if (!JunctionResolver().Resolve(wname.c_str(), &result_ptr)) { + return false; + } + *result = WstringToCstring(RemoveUncPrefixMaybe(result_ptr.get())).get(); + return true; +} + bool PathExists(const string& path) { if (path.empty()) { return false; |