Bazel client: make it compile with MSVC

Final modifications to the Bazel client code so
we can compile //src/main/cpp/...:all using MSVC.
Yay!

We still have some dependencies that don't compile
with MSVC, namely Ijar, build-runfiles,
process-wrapper, and process-tools.

Still, this change is a huge success, because now
we can add regression tests to prevent people from
introducing breaking changes to the client that
would break Windows/MSVC compilation.

It's important to point out that we can only build
this library for now, most functions in
file_windows.cc and blaze_util_windows.cc have an
empty body (they just call `pdie`).

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

--
MOS_MIGRATED_REVID=140348351
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index 8ba825b..9b8289e 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -47,6 +47,9 @@
         ],
         "//src:freebsd": [
         ],
+        "//src:windows_msvc": [
+            "-Wl,ws2_32.lib",  # for grpc
+        ],
         "//conditions:default": [
             "-lrt",
         ],
@@ -97,6 +100,8 @@
             "-lprocstat",
             "-lm",
         ],
+        "//src:windows_msvc": [
+        ],
         "//conditions:default": [
             "-lrt",
             "-ldl",
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index ea38384..6f63e16 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -36,7 +36,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
-#include <unistd.h>
 
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
@@ -1071,27 +1070,6 @@
   }
 }
 
-// A signal-safe version of fprintf(stderr, ...).
-//
-// WARNING: any output from the blaze client may be interleaved
-// with output from the blaze server.  In --curses mode,
-// the Blaze server often erases the previous line of output.
-// So, be sure to end each such message with TWO newlines,
-// otherwise it may be erased by the next message from the
-// Blaze server.
-// Also, it's a good idea to start each message with a newline,
-// in case the Blaze server has written a partial line.
-static void sigprintf(const char *format, ...) {
-  char buf[1024];
-  va_list ap;
-  va_start(ap, format);
-  int r = vsnprintf(buf, sizeof buf, format, ap);
-  va_end(ap);
-  if (write(STDERR_FILENO, buf, r) <= 0) {
-    // We don't care, just placate the compiler.
-  }
-}
-
 static void CancelServer() {
   blaze_server->Cancel();
 }
@@ -1631,7 +1609,8 @@
 void GrpcBlazeServer::SendAction(CancelThreadAction action) {
   char msg = action;
   if (!_pipe->Send(&msg, 1)) {
-    sigprintf("\nCould not interrupt server (cannot write to client pipe)\n\n");
+    blaze::SigPrintf(
+        "\nCould not interrupt server (cannot write to client pipe)\n\n");
   }
 }
 
diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h
index 1542b66..ba5b685 100644
--- a/src/main/cpp/blaze_util_platform.h
+++ b/src/main/cpp/blaze_util_platform.h
@@ -44,6 +44,9 @@
   SignalHandler() : _globals(nullptr), _cancel_server(nullptr) {}
 };
 
+// A signal-safe version of fprintf(stderr, ...).
+void SigPrintf(const char *format, ...);
+
 std::string GetProcessIdAsString();
 
 // Get the absolute path to the binary being executed.
diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc
index 60bf2be..99360d7 100644
--- a/src/main/cpp/blaze_util_posix.cc
+++ b/src/main/cpp/blaze_util_posix.cc
@@ -51,9 +51,6 @@
 // correctly.  (Currently only SIGPIPE uses this mechanism.)
 static volatile sig_atomic_t signal_handler_received_signal = 0;
 
-// A signal-safe version of fprintf(stderr, ...).
-static void sigprintf(const char *format, ...);
-
 // Signal handler.
 static void handler(int signum) {
   int saved_errno = errno;
@@ -63,7 +60,7 @@
   switch (signum) {
     case SIGINT:
       if (++sigint_count >= 3) {
-        sigprintf(
+        SigPrintf(
             "\n%s caught third interrupt signal; killed.\n\n",
             SignalHandler::Get().GetGlobals()->options->product_name.c_str());
         if (SignalHandler::Get().GetGlobals()->server_pid != -1) {
@@ -71,13 +68,13 @@
         }
         ExitImmediately(1);
       }
-      sigprintf(
+      SigPrintf(
           "\n%s caught interrupt signal; shutting down.\n\n",
           SignalHandler::Get().GetGlobals()->options->product_name.c_str());
       SignalHandler::Get().CancelServer();
       break;
     case SIGTERM:
-      sigprintf(
+      SigPrintf(
           "\n%s caught terminate signal; shutting down.\n\n",
           SignalHandler::Get().GetGlobals()->options->product_name.c_str());
       SignalHandler::Get().CancelServer();
@@ -86,7 +83,7 @@
       signal_handler_received_signal = SIGPIPE;
       break;
     case SIGQUIT:
-      sigprintf("\nSending SIGQUIT to JVM process %d (see %s).\n\n",
+      SigPrintf("\nSending SIGQUIT to JVM process %d (see %s).\n\n",
                 SignalHandler::Get().GetGlobals()->server_pid,
                 SignalHandler::Get().GetGlobals()->jvm_log_file.c_str());
       kill(SignalHandler::Get().GetGlobals()->server_pid, SIGQUIT);
@@ -499,7 +496,7 @@
 // Blaze server.
 // Also, it's a good idea to start each message with a newline,
 // in case the Blaze server has written a partial line.
-static void sigprintf(const char *format, ...) {
+void SigPrintf(const char *format, ...) {
   char buf[1024];
   va_list ap;
   va_start(ap, format);
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index fc9b9af..d352208 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -99,9 +99,6 @@
 // correctly.  (Currently only SIGPIPE uses this mechanism.)
 static volatile sig_atomic_t signal_handler_received_signal = 0;
 
-// A signal-safe version of fprintf(stderr, ...).
-static void sigprintf(const char* format, ...);
-
 // Signal handler.
 static void handler(int signum) {
   int saved_errno = errno;
@@ -111,7 +108,7 @@
   switch (signum) {
     case SIGINT:
       if (++sigint_count >= 3) {
-        sigprintf(
+        SigPrintf(
             "\n%s caught third interrupt signal; killed.\n\n",
             SignalHandler::Get().GetGlobals()->options->product_name.c_str());
         if (SignalHandler::Get().GetGlobals()->server_pid != -1) {
@@ -119,13 +116,13 @@
         }
         ExitImmediately(1);
       }
-      sigprintf(
+      SigPrintf(
           "\n%s caught interrupt signal; shutting down.\n\n",
           SignalHandler::Get().GetGlobals()->options->product_name.c_str());
       SignalHandler::Get().CancelServer();
       break;
     case SIGTERM:
-      sigprintf(
+      SigPrintf(
           "\n%s caught terminate signal; shutting down.\n\n",
           SignalHandler::Get().GetGlobals()->options->product_name.c_str());
       SignalHandler::Get().CancelServer();
@@ -134,7 +131,7 @@
       signal_handler_received_signal = SIGPIPE;
       break;
     case SIGQUIT:
-      sigprintf("\nSending SIGQUIT to JVM process %d (see %s).\n\n",
+      SigPrintf("\nSending SIGQUIT to JVM process %d (see %s).\n\n",
                 SignalHandler::Get().GetGlobals()->server_pid,
                 SignalHandler::Get().GetGlobals()->jvm_log_file.c_str());
       kill(SignalHandler::Get().GetGlobals()->server_pid, SIGQUIT);
@@ -172,6 +169,8 @@
   }
 }
 
+#endif  // COMPILER_MSVC
+
 // A signal-safe version of fprintf(stderr, ...).
 //
 // WARNING: any output from the blaze client may be interleaved
@@ -182,7 +181,10 @@
 // Blaze server.
 // Also, it's a good idea to start each message with a newline,
 // in case the Blaze server has written a partial line.
-static void sigprintf(const char *format, ...) {
+void SigPrintf(const char *format, ...) {
+#ifdef COMPILER_MSVC
+  pdie(255, "blaze::SigPrintf is not implemented on Windows");
+#else  // not COMPILER_MSVC
   char buf[1024];
   va_list ap;
   va_start(ap, format);
@@ -191,9 +193,8 @@
   if (write(STDERR_FILENO, buf, r) <= 0) {
     // We don't care, just placate the compiler.
   }
-}
-
 #endif  // COMPILER_MSVC
+}
 
 static void PrintError(const string& op) {
     DWORD last_error = ::GetLastError();
diff --git a/src/main/cpp/global_variables.h b/src/main/cpp/global_variables.h
index e11ea1a..063cdbb 100644
--- a/src/main/cpp/global_variables.h
+++ b/src/main/cpp/global_variables.h
@@ -22,6 +22,8 @@
 #include <string>
 #include <vector>
 
+#include "src/main/cpp/util/port.h"  // pid_t on Windows/MSVC
+
 namespace blaze {
 
 class OptionProcessor;
@@ -52,6 +54,9 @@
   // The path of the JVM executable that should be used to launch Blaze.
   std::string jvm_path;
 
+  // TODO(laszlocsomor) 2016-11-28: move pid_t usage out of here and whereever
+  // else it appears. Find some way to not have to declare a pid_t here, either
+  // by making PID handling platform-independent or some other idea.
   pid_t server_pid;
 
   // Contains the relative paths of all the files in the attached zip, and is
diff --git a/src/main/cpp/util/file.cc b/src/main/cpp/util/file.cc
index 41242e7..2f6e6c6 100644
--- a/src/main/cpp/util/file.cc
+++ b/src/main/cpp/util/file.cc
@@ -15,6 +15,8 @@
 
 #include <errno.h>
 #include <limits.h>  // PATH_MAX
+
+#include <algorithm>
 #include <cstdlib>
 #include <vector>
 
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index 6cab2b4..cbf17d1 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -16,11 +16,33 @@
 #include <windows.h>
 
 #include "src/main/cpp/util/errors.h"
+#include "src/main/cpp/util/file.h"
 
 namespace blaze_util {
 
 using std::string;
 
+class WindowsPipe : public IPipe {
+ public:
+  bool Send(void* buffer, int size) override {
+    // TODO(bazel-team): implement this.
+    pdie(255, "blaze_util::WindowsPipe::Send is not yet implemented");
+    return false;
+  }
+
+  int Receive(void* buffer, int size) override {
+    // TODO(bazel-team): implement this.
+    pdie(255, "blaze_util::WindowsPipe::Receive is not yet implemented");
+    return 0;
+  }
+};
+
+IPipe* CreatePipe() {
+  // TODO(bazel-team): implement this.
+  pdie(255, "blaze_util::CreatePipe is not implemented on Windows");
+  return nullptr;
+}
+
 bool ReadFile(const string& filename, string* content, int max_size) {
   // TODO(bazel-team): implement this.
   pdie(255, "blaze_util::ReadFile is not implemented on Windows");
diff --git a/src/main/cpp/util/port.h b/src/main/cpp/util/port.h
index bb70406..393648e 100644
--- a/src/main/cpp/util/port.h
+++ b/src/main/cpp/util/port.h
@@ -111,4 +111,12 @@
 
 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
 
+#ifdef COMPILER_MSVC
+// TODO(laszlocsomor) 2016-11-28: move pid_t usage out of global_variables.h and
+// whereever else it appears. Find some way to not have to declare a pid_t here,
+// either by making PID handling platform-independent or some other idea; remove
+// the following typedef afterwards.
+typedef int pid_t;
+#endif  // COMPILER_MSVC
+
 #endif  // BAZEL_SRC_MAIN_CPP_UTIL_PORT_H_