Ijar: extract file writing logic to platform_utils

This change takes us closer to compiling ijar,
thus Bazel, with MSVC.

Also update the StatFile method added by
unknown commit to report any errors.

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

--
MOS_MIGRATED_REVID=140719249
diff --git a/third_party/ijar/platform_utils.cc b/third_party/ijar/platform_utils.cc
index 19e10c0..a3c4cce 100644
--- a/third_party/ijar/platform_utils.cc
+++ b/third_party/ijar/platform_utils.cc
@@ -38,6 +38,7 @@
 #else   // not COMPILER_MSVC
   struct stat statst;
   if (stat(path, &statst) < 0) {
+    fprintf(stderr, "Cannot stat file %s: %s\n", path, strerror(errno));
     return false;
   }
   result->total_size = statst.st_size;
@@ -47,4 +48,31 @@
 #endif  // COMPILER_MSVC
 }
 
+bool write_file(const char* path, mode_t perm, const void* data, size_t size) {
+#ifdef COMPILER_MSVC
+  // TODO(laszlocsomor) 2016-12-01: implement this and other methods, in order
+  // to close https://github.com/bazelbuild/bazel/issues/2157.
+  fprintf(stderr, "Not yet implemented on Windows\n");
+  return false;
+#else   // not COMPILER_MSVC
+  int fd = open(path, O_CREAT | O_WRONLY, perm);
+  if (fd < 0) {
+    fprintf(stderr, "Cannot open file %s for writing: %s\n",
+            path, strerror(errno));
+    return false;
+  }
+  bool result = true;
+  if (write(fd, data, size) != size) {
+    fprintf(stderr, "Cannot write %zu bytes to file %s: %s\n",
+            size, path, strerror(errno));
+    result = false;
+  }
+  if (close(fd)) {
+    fprintf(stderr, "Cannot close file %s: %s\n", path, strerror(errno));
+    result = false;
+  }
+  return result;
+#endif  // COMPILER_MSVC
+}
+
 }  // namespace devtools_ijar
diff --git a/third_party/ijar/platform_utils.h b/third_party/ijar/platform_utils.h
index cb48819..9ba9247 100644
--- a/third_party/ijar/platform_utils.h
+++ b/third_party/ijar/platform_utils.h
@@ -35,8 +35,15 @@
 
 // Writes stat data into `result` about the file under `path`.
 // Returns true upon success: file is found and can be stat'ed.
+// Returns false upon failure and reports the error to stderr.
 bool stat_file(const char* path, Stat* result);
 
+// Writes `size` bytes from `data` into file under `path`.
+// The file is created or overwritten and is set to have `perm` permissions.
+// Returns true upon success: file is created and all data is written.
+// Returns false upon failure and reports the error to stderr.
+bool write_file(const char* path, mode_t perm, const void* data, size_t size);
+
 }  // namespace devtools_ijar
 
 #endif  // THIRD_PARTY_IJAR_PLATFORM_UTILS_H_
diff --git a/third_party/ijar/zip_main.cc b/third_party/ijar/zip_main.cc
index 351faba..4347f01 100644
--- a/third_party/ijar/zip_main.cc
+++ b/third_party/ijar/zip_main.cc
@@ -37,13 +37,6 @@
 
 namespace devtools_ijar {
 
-#define SYSCALL(expr)  do { \
-                         if ((expr) < 0) { \
-                           perror(#expr); \
-                           abort(); \
-                         } \
-                       } while (0)
-
 //
 // A ZipExtractorProcessor that extract files in the ZIP file.
 //
@@ -142,20 +135,12 @@
   }
   if (extract_) {
     char path[PATH_MAX];
-    int fd;
     concat_path(path, PATH_MAX, output_root_, filename);
     // Directories created must have executable bit set and be owner writeable.
     // Otherwise, we cannot write or create any file inside.
     mkdirs(path, perm | S_IWUSR | S_IXUSR);
-    if (!isdir) {
-      fd = open(path, O_CREAT | O_WRONLY, perm);
-      if (fd < 0) {
-        fprintf(stderr, "Cannot open file %s for writing: %s\n",
-                path, strerror(errno));
-        abort();
-      }
-      SYSCALL(write(fd, data, size));
-      SYSCALL(close(fd));
+    if (!isdir && !write_file(path, perm, data, size)) {
+      abort();
     }
   }
 }
@@ -230,7 +215,6 @@
   file_stat.file_mode = 0666;
   if (file != NULL) {
     if (!stat_file(file, &file_stat)) {
-      fprintf(stderr, "Cannot stat file %s: %s.\n", file, strerror(errno));
       return -1;
     }
   }
@@ -293,7 +277,6 @@
 char **read_filelist(char *filename) {
   Stat file_stat;
   if (!stat_file(filename, &file_stat)) {
-    fprintf(stderr, "Cannot stat file %s: %s.\n", filename, strerror(errno));
     return NULL;
   }