|  | // 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 |