[LibFuzzer] Add Windows implementations of some IO functions.

This patch moves some posix specific file i/o code into a new
file, FuzzerIOPosix.cpp, and provides implementations for these
functions on Windows in FuzzerIOWindows.cpp.  This is another
incremental step towards getting libfuzzer working on Windows,
although it still should not be expected to be fully working.

Patch by Marcos Pividori
Differential Revision: https://reviews.llvm.org/D27233

llvm-svn: 288275
diff --git a/llvm/lib/Fuzzer/FuzzerIO.cpp b/llvm/lib/Fuzzer/FuzzerIO.cpp
index 6cc8a8e0..5d4d415 100644
--- a/llvm/lib/Fuzzer/FuzzerIO.cpp
+++ b/llvm/lib/Fuzzer/FuzzerIO.cpp
@@ -11,26 +11,17 @@
 #include "FuzzerIO.h"
 #include "FuzzerDefs.h"
 #include "FuzzerExtFunctions.h"
-#include <iterator>
+#include <algorithm>
+#include <cstdarg>
 #include <fstream>
-#include <dirent.h>
+#include <iterator>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
-#include <cstdarg>
-#include <cstdio>
 
 namespace fuzzer {
 
 static FILE *OutputFile = stderr;
 
-bool IsFile(const std::string &Path) {
-  struct stat St;
-  if (stat(Path.c_str(), &St))
-    return false;
-  return S_ISREG(St.st_mode);
-}
-
 long GetEpoch(const std::string &Path) {
   struct stat St;
   if (stat(Path.c_str(), &St))
@@ -38,29 +29,6 @@
   return St.st_mtime;
 }
 
-static void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
-                                    std::vector<std::string> *V, bool TopDir) {
-  auto E = GetEpoch(Dir);
-  if (Epoch)
-    if (E && *Epoch >= E) return;
-
-  DIR *D = opendir(Dir.c_str());
-  if (!D) {
-    Printf("No such directory: %s; exiting\n", Dir.c_str());
-    exit(1);
-  }
-  while (auto E = readdir(D)) {
-    std::string Path = DirPlusFile(Dir, E->d_name);
-    if (E->d_type == DT_REG || E->d_type == DT_LNK)
-      V->push_back(Path);
-    else if (E->d_type == DT_DIR && *E->d_name != '.')
-      ListFilesInDirRecursive(Path, Epoch, V, false);
-  }
-  closedir(D);
-  if (Epoch && TopDir)
-    *Epoch = E;
-}
-
 Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
   std::ifstream T(Path);
   if (ExitOnError && !T) {
@@ -79,10 +47,6 @@
   return Res;
 }
 
-void DeleteFile(const std::string &Path) {
-  unlink(Path.c_str());
-}
-
 std::string FileToString(const std::string &Path) {
   std::ifstream T(Path);
   return std::string((std::istreambuf_iterator<char>(T)),
@@ -121,23 +85,25 @@
 
 std::string DirPlusFile(const std::string &DirPath,
                         const std::string &FileName) {
-  return DirPath + "/" + FileName;
+  return DirPath + GetSeparator() + FileName;
 }
 
 void DupAndCloseStderr() {
-  int OutputFd = dup(2);
+  int OutputFd = DuplicateFile(2);
   if (OutputFd > 0) {
-    FILE *NewOutputFile = fdopen(OutputFd, "w");
+    FILE *NewOutputFile = OpenFile(OutputFd, "w");
     if (NewOutputFile) {
       OutputFile = NewOutputFile;
       if (EF->__sanitizer_set_report_fd)
         EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));
-      close(2);
+      CloseFile(2);
     }
   }
 }
 
-void CloseStdout() { close(1); }
+void CloseStdout() {
+  CloseFile(1);
+}
 
 void Printf(const char *Fmt, ...) {
   va_list ap;