Bazel client: MakeCanonical into file_<platform>

Move MakeCanonical into platform-specific files.
Also change the signature of
blaze.cc:CheckBinaryPath to return the binary path
instead of mutating `globals`.

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

--
MOS_MIGRATED_REVID=140128173
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index f74fa0e..9615ad7 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -1203,22 +1203,14 @@
   globals->options = globals->option_processor->GetParsedStartupOptions();
 }
 
-// Returns the canonical form of a path.
-static string MakeCanonical(const char *path) {
-  char *resolved_path = realpath(path, NULL);
-  if (resolved_path == NULL) {
-    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
-         "realpath('%s') failed", path);
-  }
-
-  string ret = resolved_path;
-  free(resolved_path);
-  return ret;
-}
-
 // Compute the globals globals->cwd and globals->workspace.
 static void ComputeWorkspace() {
-  globals->cwd = MakeCanonical(blaze_util::GetCwd().c_str());
+  globals->cwd = blaze_util::MakeCanonical(blaze_util::GetCwd().c_str());
+  if (globals->cwd.empty()) {
+    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
+         "blaze_util::MakeCanonical('%s') failed",
+         blaze_util::GetCwd().c_str());
+  }
   globals->workspace = WorkspaceLayout::GetWorkspace(globals->cwd);
 }
 
@@ -1272,7 +1264,11 @@
   }
   ExcludePathFromBackup(output_base);
 
-  globals->options->output_base = MakeCanonical(output_base);
+  globals->options->output_base = blaze_util::MakeCanonical(output_base);
+  if (globals->options->output_base.empty()) {
+    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
+         "blaze_util::MakeCanonical('%s') failed", output_base);
+  }
 
   globals->lockfile = globals->options->output_base + "/lock";
   globals->jvm_log_file = globals->options->output_base + "/server/jvm.out";
@@ -1321,19 +1317,18 @@
   blaze::SetEnv("LC_CTYPE", "en_US.ISO-8859-1");
 }
 
-static void CheckBinaryPath(const string& argv0) {
+static string CheckAndGetBinaryPath(const string& argv0) {
   if (argv0[0] == '/') {
-    globals->binary_path = argv0;
+    return argv0;
   } else {
     string abs_path = globals->cwd + '/' + argv0;
-    char *resolved_path = realpath(abs_path.c_str(), NULL);
-    if (resolved_path) {
-      globals->binary_path = resolved_path;
-      free(resolved_path);
+    string resolved_path = blaze_util::MakeCanonical(abs_path.c_str());
+    if (!resolved_path.empty()) {
+      return resolved_path;
     } else {
       // This happens during our integration tests, but thats okay, as we won't
       // log the invocation anyway.
-      globals->binary_path = abs_path;
+      return abs_path;
     }
   }
 }
@@ -1351,7 +1346,7 @@
 
   // Must be done before command line parsing.
   ComputeWorkspace();
-  CheckBinaryPath(argv[0]);
+  globals->binary_path = CheckAndGetBinaryPath(argv[0]);
   ParseOptions(argc, argv);
 
   debug_log("Debug logging active");
diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h
index 7682e21..07d5b7e 100644
--- a/src/main/cpp/util/file_platform.h
+++ b/src/main/cpp/util/file_platform.h
@@ -33,6 +33,13 @@
 // Returns true if this path exists.
 bool PathExists(const std::string& path);
 
+// Returns the real, absolute path corresponding to `path`.
+// The method resolves all symlink components of `path`.
+// Returns the empty string upon error.
+//
+// This is a wrapper around realpath(3).
+std::string MakeCanonical(const char *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
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index 08a38cc..c25b928 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -106,6 +106,17 @@
   return access(path.c_str(), F_OK) == 0;
 }
 
+string MakeCanonical(const char *path) {
+  char *resolved_path = realpath(path, NULL);
+  if (resolved_path == NULL) {
+    return "";
+  } else {
+    string ret = resolved_path;
+    free(resolved_path);
+    return ret;
+  }
+}
+
 bool CanAccess(const string& path, bool read, bool write, bool exec) {
   int mode = 0;
   if (read) {
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index 1465699..72b9f47 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -32,6 +32,12 @@
   return false;
 }
 
+string MakeCanonical(const char *path) {
+  // TODO(bazel-team): implement this.
+  pdie(255, "blaze_util::MakeCanonical is not implemented on Windows");
+  return "";
+}
+
 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");