Rollback of commit 9a13899b1492738f8d1a9118cebc9ef9d90c6b34.

*** Reason for rollback ***

Fixed the problem with the CL.

*** Original change description ***

Bazel client, Windows: implement UnlinkPath

See https://github.com/bazelbuild/bazel/issues/2107

--
PiperOrigin-RevId: 144087552
MOS_MIGRATED_REVID=144087552
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index 466bae4..9d7f772 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -209,15 +209,15 @@
   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 3a5b5ac..ba3e777 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -43,6 +43,12 @@
 // 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);
 
diff --git a/src/test/cpp/util/file_windows_test.cc b/src/test/cpp/util/file_windows_test.cc
index 5c2f68e..1d73d65 100644
--- a/src/test/cpp/util/file_windows_test.cc
+++ b/src/test/cpp/util/file_windows_test.cc
@@ -290,6 +290,37 @@
   ASSERT_FALSE(PathExists(JoinPath(tmpdir, "junc2")));
 }
 
+TEST(FileTest, TestUnlinkPath) {
+  string tmpdir(GetTestTmpDir());
+  ASSERT_LT(0, tmpdir.size());
+  ASSERT_TRUE(PathExists(tmpdir));
+
+  // Create a directory under `tempdir`, a file inside it, and a junction
+  // pointing to it.
+  string dir1(JoinPath(tmpdir, "dir1"));
+  ASSERT_EQ(0, mkdir(dir1.c_str()));
+  FILE* fh = fopen(JoinPath(dir1, "foo.txt").c_str(), "wt");
+  ASSERT_NE(nullptr, fh);
+  ASSERT_LT(0, fprintf(fh, "hello\n"));
+  fclose(fh);
+  string junc1(JoinPath(tmpdir, "junc1"));
+  RunCommand(string("cmd.exe /C mklink /J \"") + junc1 + "\" \"" + dir1 +
+             "\" >NUL 2>NUL");
+  ASSERT_TRUE(PathExists(junc1));
+  ASSERT_TRUE(PathExists(JoinPath(junc1, "foo.txt")));
+
+  // Non-existent files cannot be unlinked.
+  ASSERT_FALSE(UnlinkPath("does.not.exist"));
+  // Directories cannot be unlinked.
+  ASSERT_FALSE(UnlinkPath(dir1));
+  // Junctions can be unlinked, even if the pointed directory is not empty.
+  ASSERT_TRUE(UnlinkPath(JoinPath(junc1, "foo.txt")));
+  // Files can be unlinked.
+  ASSERT_TRUE(UnlinkPath(junc1));
+  // Clean up the now empty directory.
+  ASSERT_EQ(0, rmdir(dir1.c_str()));
+}
+
 TEST(FileTest, TestIsDirectory) {
   ASSERT_FALSE(IsDirectory(""));