Enable bssl (md5sum, sha256sum, etc.) on Windows.

We deal with the difference between binary and text modes on Windows by
doing all I/O in binary mode (including, in particular,
stdin/stdout/stderr) and by treating text mode as equivalent to binary
mode (i.e. we use Unix line ending semantics).

Change-Id: I76a46d8d02cd7efe1931c8272d8f2c311aef3acb
Reviewed-on: https://boringssl-review.googlesource.com/3070
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/tool/tool.cc b/tool/tool.cc
index 88b6f24..3b24be5 100644
--- a/tool/tool.cc
+++ b/tool/tool.cc
@@ -18,7 +18,10 @@
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 
-#if !defined(OPENSSL_WINDOWS)
+#if defined(OPENSSL_WINDOWS)
+#include <fcntl.h>
+#include <io.h>
+#else
 #include <libgen.h>
 #endif
 
@@ -26,13 +29,13 @@
 #if !defined(OPENSSL_WINDOWS)
 bool Client(const std::vector<std::string> &args);
 bool Server(const std::vector<std::string> &args);
+#endif
 bool MD5Sum(const std::vector<std::string> &args);
 bool SHA1Sum(const std::vector<std::string> &args);
 bool SHA224Sum(const std::vector<std::string> &args);
 bool SHA256Sum(const std::vector<std::string> &args);
 bool SHA384Sum(const std::vector<std::string> &args);
 bool SHA512Sum(const std::vector<std::string> &args);
-#endif
 bool DoPKCS12(const std::vector<std::string> &args);
 bool Speed(const std::vector<std::string> &args);
 
@@ -51,13 +54,13 @@
   { "s_client", Client },
   { "server", Server },
   { "s_server", Server },
+#endif
   { "md5sum", MD5Sum },
   { "sha1sum", SHA1Sum },
   { "sha224sum", SHA224Sum },
   { "sha256sum", SHA256Sum },
   { "sha384sum", SHA384Sum },
   { "sha512sum", SHA512Sum },
-#endif
   { "", nullptr },
 };
 
@@ -87,6 +90,25 @@
 }
 
 int main(int argc, char **argv) {
+#if defined(OPENSSL_WINDOWS)
+  // Read and write in binary mode. This makes bssl on Windows consistent with
+  // bssl on other platforms, and also makes it consistent with MSYS's commands
+  // like diff(1) and md5sum(1). This is especially important for the digest
+  // commands.
+  if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
+    perror("_setmode(_fileno(stdin), O_BINARY)");
+    return 1;
+  }
+  if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
+    perror("_setmode(_fileno(stdout), O_BINARY)");
+    return 1;
+  }
+  if (_setmode(_fileno(stderr), _O_BINARY) == -1) {
+    perror("_setmode(_fileno(stderr), O_BINARY)");
+    return 1;
+  }
+#endif
+
   SSL_library_init();
 
   int starting_arg = 1;