diff options
author | Laszlo Csomor <laszlocsomor@google.com> | 2017-01-11 09:58:11 +0000 |
---|---|---|
committer | Marcel Hlopko <hlopko@google.com> | 2017-01-11 10:02:55 +0000 |
commit | a6d8e28318d931dfa7ac047c8c524a26f7501ce5 (patch) | |
tree | 2a05c8fab9dedd8d9056c1630dc3b89b75970fe2 /src/main/cpp/util | |
parent | d9fc1759b1f57fe2b3c96f28b1d7f442b6908beb (diff) |
Bazel client, Windows: implement UnlinkPath
This was committed and rolled back twice, once
because I forgot to update file_posix.cc, and
again because the roll-forward was somehow only
partial.
This is a clean attempt at submitting the same
thing again.
See https://github.com/bazelbuild/bazel/issues/2107
--
PiperOrigin-RevId: 144179954
MOS_MIGRATED_REVID=144179954
Diffstat (limited to 'src/main/cpp/util')
-rw-r--r-- | src/main/cpp/util/file_posix.cc | 8 | ||||
-rw-r--r-- | src/main/cpp/util/file_windows.cc | 36 |
2 files changed, 34 insertions, 10 deletions
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index c1a313a1f3..cc8cadbcf0 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc @@ -209,15 +209,15 @@ bool WriteFile(const void *data, size_t size, const string &filename) { return result; } -bool UnlinkPath(const string &file_path) { - return unlink(file_path.c_str()) == 0; -} - // TODO(bazel-team): implement all functions in file_windows.cc, use them from // MSYS, remove file_posix.cc from the `srcs` of // //src/main/cpp/util:file when building for MSYS, and remove all // #ifndef __CYGWIN__ directives. #ifndef __CYGWIN__ +bool UnlinkPath(const string &file_path) { + return unlink(file_path.c_str()) == 0; +} + bool PathExists(const string& path) { return access(path.c_str(), F_OK) == 0; } diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index 4293d5ead7..22ab715f23 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc @@ -43,6 +43,12 @@ static unique_ptr<WCHAR[]> GetCwdW(); // necessary. static bool IsDirectoryW(const wstring& path); +// Returns true the file or junction at `path` is successfully deleted. +// Returns false otherwise, or if `path` doesn't exist or is a directory. +// `path` must be a normalized Windows path, with UNC prefix (and absolute) if +// necessary. +static bool UnlinkPathW(const wstring& path); + // Like `AsWindowsPath` but the result is absolute and has UNC prefix if needed. static bool AsWindowsPathWithUncPrefix(const string& path, wstring* wpath); @@ -389,14 +395,32 @@ bool WriteFile(const void* data, size_t size, const string& filename) { #else // not COMPILER_MSVC #endif // COMPILER_MSVC -#ifdef COMPILER_MSVC +static bool UnlinkPathW(const wstring& path) { + DWORD attrs = ::GetFileAttributesW(path.c_str()); + if (attrs == INVALID_FILE_ATTRIBUTES) { + // Path does not exist. + return false; + } + if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + if (!(attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { + // Path is a directory; unlink(2) also cannot remove directories. + return false; + } + // Otherwise it's a junction, remove using RemoveDirectoryW. + return ::RemoveDirectoryW(path.c_str()) == TRUE; + } else { + // Otherwise it's a file, remove using DeleteFileW. + return ::DeleteFileW(path.c_str()) == TRUE; + } +} + bool UnlinkPath(const string& file_path) { - // TODO(bazel-team): implement this. - pdie(255, "blaze_util::UnlinkPath is not implemented on Windows"); - return false; + wstring wpath; + if (!AsWindowsPathWithUncPrefix(file_path, &wpath)) { + return false; + } + return UnlinkPathW(wpath); } -#else // not COMPILER_MSVC -#endif // COMPILER_MSVC HANDLE OpenDirectory(const WCHAR* path, bool read_write) { return ::CreateFileW( |