| // Copyright 2016 The Bazel Authors. All rights reserved. | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 | #include "src/tools/singlejar/test_util.h" | 
 |  | 
 | #include <fcntl.h> | 
 | #include <stdarg.h> | 
 | #include <stdlib.h> | 
 | #include <sys/types.h> | 
 |  | 
 | #ifndef _WIN32 | 
 | #include <unistd.h> | 
 | #endif | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "src/main/cpp/util/file.h" | 
 | #include "src/main/cpp/util/file_platform.h" | 
 | #include "src/main/cpp/util/path.h" | 
 | #include "src/main/cpp/util/strings.h" | 
 |  | 
 | #include "googletest/include/gtest/gtest.h" | 
 |  | 
 | #ifdef _WIN32 | 
 | #define popen _popen | 
 | #define pclose _pclose | 
 | #endif | 
 |  | 
 | namespace singlejar_test_util { | 
 |  | 
 | bool AllocateFile(const string &name, size_t size) { | 
 | #ifdef _WIN32 | 
 |   int fd = _sopen(name.c_str(), _O_RDWR | _O_CREAT | _O_BINARY, _SH_DENYNO, | 
 |                   _S_IREAD | _S_IWRITE); | 
 |   int success = _chsize_s(fd, size); | 
 |   _close(fd); | 
 |   if (success < 0) { | 
 |     perror(strerror(errno)); | 
 |     return false; | 
 |   } | 
 |   return true; | 
 | #else | 
 |   int fd = open(name.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0777); | 
 |   if (fd < 0) { | 
 |     perror(name.c_str()); | 
 |     return false; | 
 |   } | 
 |   if (size) { | 
 |     if (ftruncate(fd, size) == 0) { | 
 |       return close(fd) == 0; | 
 |     } else { | 
 |       auto last_error = errno; | 
 |       close(fd); | 
 |       errno = last_error; | 
 |       return false; | 
 |     } | 
 |   } else { | 
 |     return close(fd) == 0; | 
 |   } | 
 | #endif | 
 | } | 
 |  | 
 | int RunCommand(const char *cmd, ...) { | 
 |   string args_string(cmd); | 
 |   va_list ap; | 
 |   va_start(ap, cmd); | 
 |   for (const char *arg = va_arg(ap, const char *); arg; | 
 |        arg = va_arg(ap, const char *)) { | 
 |     args_string += ' '; | 
 |     args_string += arg; | 
 |   } | 
 |   va_end(ap); | 
 |   fprintf(stderr, "Arguments: %s\n", args_string.c_str()); | 
 |   return system(args_string.c_str()); | 
 | } | 
 |  | 
 | // List zip file contents. | 
 | void LsZip(const char *zip_name) { | 
 | #if !defined(__APPLE__) | 
 |   RunCommand("unzip", "-v", zip_name, nullptr); | 
 | #endif | 
 | } | 
 |  | 
 | string OutputFilePath(const string &relpath) { | 
 |   const char *out_dir = getenv("TEST_TMPDIR"); | 
 |   return blaze_util::JoinPath((nullptr == out_dir) ? "." : out_dir, | 
 |                               relpath.c_str()); | 
 | } | 
 |  | 
 | int VerifyZip(const string &zip_path) { | 
 |   string verify_command; | 
 |   blaze_util::StringPrintf(&verify_command, "zip -Tv %s", zip_path.c_str()); | 
 |   return system(verify_command.c_str()); | 
 | } | 
 |  | 
 | string GetEntryContents(const string &zip_path, const string &entry_name) { | 
 |   string contents; | 
 |   string command; | 
 |   blaze_util::StringPrintf(&command, "unzip -p %s %s", zip_path.c_str(), | 
 |                            entry_name.c_str()); | 
 | #ifdef _WIN32 | 
 |   // "b" is Microsoft-specific. It's necessary, because without it the popen | 
 |   // implementation will strip "\r\n" to "\n" and make many tests fail. | 
 |   FILE *fp = popen(command.c_str(), "rb"); | 
 | #else | 
 |   FILE *fp = popen(command.c_str(), "r"); | 
 | #endif | 
 |   if (!fp) { | 
 |     ADD_FAILURE() << "Command " << command << " failed."; | 
 |     return string(""); | 
 |   } | 
 |  | 
 |   char buf[1024]; | 
 |   while (fgets(buf, sizeof(buf), fp)) { | 
 |     contents.append(buf); | 
 |   } | 
 |   if (feof(fp) && !ferror(fp) && !pclose(fp)) { | 
 |     return contents; | 
 |   } | 
 |   ADD_FAILURE() << "Command " << command << " failed on close."; | 
 |   return string(""); | 
 | } | 
 |  | 
 | string CreateTextFile(const string& relpath, const char *contents) { | 
 |   string out_path = OutputFilePath(relpath); | 
 |   blaze_util::MakeDirectories(blaze_util::Dirname(out_path), 0777); | 
 |   if (blaze_util::WriteFile(contents, out_path)) { | 
 |     return out_path; | 
 |   } | 
 |   ADD_FAILURE() << "Cannot write " << out_path; | 
 |   return string(""); | 
 | } | 
 |  | 
 | }  // namespace singlejar_test_util |