blaze_utils: fork file handling for platforms

This commit repurposes file_posix.cc to be the
POSIX API file handling implementation, and adds
file_windows.cc for the Win32 API implementations.
Furthermore it introduces file_platform.h that
declares the interface.

Subsequent changes will replace POSIX API calls in
the rest of the C++ code with these abstract
methods.

Motivation: our code is so littered with
POSIX-isms that we need an abstraction layer if we
hope to compile it with MSVC.

--
MOS_MIGRATED_REVID=138615822
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index 169caa8..d74a325 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -52,14 +52,7 @@
     deps = [
         "//src/main/cpp/util",
         "//src/main/cpp/util:blaze_exit_code",
-    ] + select({
-        "//src:darwin": [],
-        "//src:darwin_x86_64": [],
-        "//src:freebsd": [],
-        "//src:windows": [],
-        "//src:windows_msvc": [],
-        "//conditions:default": ["//src/main/cpp/util:file_posix"],
-    }),
+    ],
 )
 
 cc_library(
diff --git a/src/main/cpp/blaze_util_linux.cc b/src/main/cpp/blaze_util_linux.cc
index c270821..0057e3d 100644
--- a/src/main/cpp/blaze_util_linux.cc
+++ b/src/main/cpp/blaze_util_linux.cc
@@ -30,7 +30,7 @@
 #include "src/main/cpp/util/errors.h"
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
-#include "src/main/cpp/util/file_posix.h"
+#include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/port.h"
 #include "src/main/cpp/util/strings.h"
 
diff --git a/src/main/cpp/util/BUILD b/src/main/cpp/util/BUILD
index 9a6a60a..7537ac5 100644
--- a/src/main/cpp/util/BUILD
+++ b/src/main/cpp/util/BUILD
@@ -6,6 +6,7 @@
     hdrs = [
         "errors.h",
         "file.h",
+        "file_platform.h",
         "numbers.h",
         "port.h",
     ],
@@ -14,6 +15,7 @@
         ":blaze_exit_code",
         ":errors",
         ":file",
+        ":file_platform",
         ":numbers",
         ":port",
         ":strings",
@@ -21,9 +23,16 @@
 )
 
 cc_library(
-    name = "file_posix",
-    srcs = ["file_posix.cc"],
-    hdrs = ["file_posix.h"],
+    name = "file_platform",
+    srcs = select({
+        "//src:windows_msvc": [
+            "file_windows.cc",
+        ],
+        "//conditions:default": [
+            "file_posix.cc",
+        ],
+    }),
+    hdrs = ["file_platform.h"],
     visibility = ["//src/main/cpp:__pkg__"],
     deps = [
         ":blaze_exit_code",
diff --git a/src/main/cpp/util/file_posix.h b/src/main/cpp/util/file_platform.h
similarity index 62%
rename from src/main/cpp/util/file_posix.h
rename to src/main/cpp/util/file_platform.h
index 1d247bc..6d00daf 100644
--- a/src/main/cpp/util/file_posix.h
+++ b/src/main/cpp/util/file_platform.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef BAZEL_SRC_MAIN_CPP_UTIL_FILE_POSIX_H_
-#define BAZEL_SRC_MAIN_CPP_UTIL_FILE_POSIX_H_
+#ifndef BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_
+#define BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_
 
 #include <string>
 
@@ -24,6 +24,16 @@
 // looking up PATH fails.
 std::string Which(const std::string &executable);
 
+// Returns true if this path exists.
+bool PathExists(const std::string& path);
+
+// Returns true if the path exists and can be accessed to read/write as desired.
+//
+// If `exec` is true and the path refers to a file, it means the file must be
+// executable; if the path is a directory, it means the directory must be
+// openable.
+bool CanAccess(const std::string& path, bool read, bool write, bool exec);
+
 }  // namespace blaze_util
 
-#endif  // BAZEL_SRC_MAIN_CPP_UTIL_FILE_POSIX_H_
+#endif  // BAZEL_SRC_MAIN_CPP_UTIL_FILE_PLATFORM_H_
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index ff85e21..11f5d10 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -11,7 +11,7 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-#include "src/main/cpp/util/file_posix.h"
+#include "src/main/cpp/util/file_platform.h"
 
 #include <sys/stat.h>
 #include <stdlib.h>  // getenv
@@ -53,4 +53,22 @@
   return "";
 }
 
+bool PathExists(const string& path) {
+  return access(path.c_str(), F_OK) == 0;
+}
+
+bool CanAccess(const string& path, bool read, bool write, bool exec) {
+  int mode = 0;
+  if (read) {
+    mode |= R_OK;
+  }
+  if (write) {
+    mode |= W_OK;
+  }
+  if (exec) {
+    mode |= X_OK;
+  }
+  return access(path.c_str(), mode) == 0;
+}
+
 }  // namespace blaze_util
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
new file mode 100644
index 0000000..34f8bcf
--- /dev/null
+++ b/src/main/cpp/util/file_windows.cc
@@ -0,0 +1,36 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "src/main/cpp/util/file_platform.h"
+
+#include <windows.h>
+
+namespace blaze_util {
+
+using std::string;
+
+string Which(const string &executable) {
+  pdie(255, "blaze_util::Which is not implemented on Windows");
+}
+
+bool PathExists(const string& path) {
+  // TODO(bazel-team): implement this.
+  pdie(255, "blaze_util::PathExists is not implemented on Windows");
+}
+
+bool CanAccess(const string& path, bool read, bool write, bool exec) {
+  // TODO(bazel-team): implement this.
+  pdie(255, "blaze_util::CanAccess is not implemented on Windows");
+}
+
+}  // namespace blaze_util