diff --git a/src/tools/singlejar/BUILD b/src/tools/singlejar/BUILD index c9e6b21d2bb4ba..6e72e4ea6aad58 100644 --- a/src/tools/singlejar/BUILD +++ b/src/tools/singlejar/BUILD @@ -355,6 +355,7 @@ cc_library( deps = [ ":diag", ":port", + "//src/main/cpp/util", ], ) @@ -413,10 +414,7 @@ cc_library( hdrs = ["test_util.h"], deps = [ "//src/main/cpp/util", - # TODO(laszlocsomor) Use @bazel_tools//tools/cpp/runfiles after Bazel is - # released with - # https://github.com/bazelbuild/bazel/commit/23bc3bee79d8a8b8dc15bbfb6072ec9f965dff96. - "//tools/cpp/runfiles:runfiles_src_for_singlejar_only", + "@bazel_tools//tools/cpp/runfiles", "@com_google_googletest//:gtest_main", ], ) diff --git a/src/tools/singlejar/diag.h b/src/tools/singlejar/diag.h index 6ca452afb9d459..b659f4ad11755d 100644 --- a/src/tools/singlejar/diag.h +++ b/src/tools/singlejar/diag.h @@ -33,7 +33,7 @@ #include #include #define _diag_msg(prefix, msg, ...) \ - { fprintf(stderr, prefix msg, __VA_ARGS__); } + { fprintf(stderr, prefix msg "\n", __VA_ARGS__); } #define _diag_msgx(exit_value, prefix, msg, ...) \ { \ _diag_msg(prefix, msg, __VA_ARGS__); \ diff --git a/src/tools/singlejar/input_jar.h b/src/tools/singlejar/input_jar.h index ccaf072c172c74..d1d22778d1925d 100644 --- a/src/tools/singlejar/input_jar.h +++ b/src/tools/singlejar/input_jar.h @@ -45,7 +45,10 @@ class InputJar { ~InputJar() { Close(); } +#ifndef _WIN32 + // Used by Google-internal only. Do not add more usage of it. int fd() const { return mapped_file_.fd(); } +#endif // Opens the file, memory maps it and locates Central Directory. bool Open(const std::string& path); diff --git a/src/tools/singlejar/mapped_file.h b/src/tools/singlejar/mapped_file.h index 9612b65ed621e7..741cadd337d168 100644 --- a/src/tools/singlejar/mapped_file.h +++ b/src/tools/singlejar/mapped_file.h @@ -50,16 +50,26 @@ class MappedFile { off64_t offset(const void *address) const { return reinterpret_cast(address) - mapped_start_; } + +#ifndef _WIN32 + // Used by Google-internal only. Do not add more usage of it. + // It is not available on Windows because Windows' implementation does not + // use fd at all and adding it would just make the implementation too + // complicated. int fd() const { return fd_; } +#endif + size_t size() const { return mapped_end_ - mapped_start_; } - bool is_open() const { return fd_ >= 0; } + bool is_open() const; private: unsigned char *mapped_start_; unsigned char *mapped_end_; - int fd_; #ifdef _WIN32 + /* HANDLE */ void *hFile_; /* HANDLE */ void *hMapFile_; +#else + int fd_; #endif }; diff --git a/src/tools/singlejar/mapped_file_posix.inc b/src/tools/singlejar/mapped_file_posix.inc index 637661b7199eb2..ae29a3c5f0ed9a 100644 --- a/src/tools/singlejar/mapped_file_posix.inc +++ b/src/tools/singlejar/mapped_file_posix.inc @@ -69,4 +69,6 @@ void MappedFile::Close() { } } +bool MappedFile::is_open() const { return fd_ >= 0; } + #endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ diff --git a/src/tools/singlejar/mapped_file_windows.inc b/src/tools/singlejar/mapped_file_windows.inc index a35702874baffa..bf72be1cc8264f 100644 --- a/src/tools/singlejar/mapped_file_windows.inc +++ b/src/tools/singlejar/mapped_file_windows.inc @@ -19,6 +19,7 @@ #error This code is for 64 bit Windows. #endif +#include "src/main/cpp/util/path_platform.h" #include "src/tools/singlejar/diag.h" #ifndef WIN32_LEAN_AND_MEAN @@ -32,21 +33,34 @@ MappedFile::MappedFile() : mapped_start_(nullptr), mapped_end_(nullptr), - fd_(-1), + hFile_(INVALID_HANDLE_VALUE), hMapFile_(INVALID_HANDLE_VALUE) {} +bool MappedFile::is_open() const { return hFile_ != INVALID_HANDLE_VALUE; } + bool MappedFile::Open(const std::string& path) { if (is_open()) { diag_errx(1, "%s:%d: This instance is already open", __FILE__, __LINE__); } - if ((fd_ = _open(path.c_str(), O_RDONLY | O_BINARY)) < 0) { - diag_warn("%s:%d: open %s:", __FILE__, __LINE__, path.c_str()); + + std::wstring wpath; + std::string error; + if (!blaze_util::AsAbsoluteWindowsPath(path, &wpath, &error)) { + diag_warn("%s:%d: AsAbsoluteWindowsPath failed: %s", __FILE__, __LINE__, + error.c_str()); + return false; + } + + hFile_ = CreateFileW(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); + if (hFile_ == INVALID_HANDLE_VALUE) { + diag_warn("%s:%d: CreateFileW failed for %S", __FILE__, __LINE__, + wpath.c_str()); return false; } - HANDLE hFile = reinterpret_cast(_get_osfhandle(fd_)); LARGE_INTEGER temp; - ::GetFileSizeEx(hFile, &temp); + ::GetFileSizeEx(hFile_, &temp); size_t fileSize = temp.QuadPart; if (fileSize == 0) { @@ -65,7 +79,7 @@ bool MappedFile::Open(const std::string& path) { } hMapFile_ = ::CreateFileMapping( - hFile, + hFile_, nullptr, // default security PAGE_READONLY, // read-only permission static_cast(fileSize >> 32), // size of mapping object, high @@ -75,8 +89,8 @@ bool MappedFile::Open(const std::string& path) { if (hMapFile_ == nullptr) { diag_warn("%s:%d: CreateFileMapping for %s failed", __FILE__, __LINE__, path.c_str()); - _close(fd_); - fd_ = -1; + ::CloseHandle(hFile_); + hFile_ = INVALID_HANDLE_VALUE; return false; } @@ -90,9 +104,9 @@ bool MappedFile::Open(const std::string& path) { diag_warn("%s:%d: MapViewOfFile for %s failed", __FILE__, __LINE__, path.c_str()); ::CloseHandle(hMapFile_); - _close(fd_); + ::CloseHandle(hFile_); + hFile_ = INVALID_HANDLE_VALUE; hMapFile_ = INVALID_HANDLE_VALUE; - fd_ = -1; return false; } @@ -109,8 +123,8 @@ void MappedFile::Close() { ::CloseHandle(hMapFile_); hMapFile_ = INVALID_HANDLE_VALUE; } - _close(fd_); - fd_ = -1; + ::CloseHandle(hFile_); + hFile_ = INVALID_HANDLE_VALUE; mapped_start_ = mapped_end_ = nullptr; } } diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc index 89ca300f465cd0..2e70fec5eaa402 100644 --- a/src/tools/singlejar/output_jar.cc +++ b/src/tools/singlejar/output_jar.cc @@ -77,7 +77,7 @@ OutputJar::OutputJar() "Created-By: singlejar\r\n"); } -static std::string Basename(const std::string& path) { +static std::string Basename(const std::string &path) { size_t pos = path.rfind('/'); if (pos == std::string::npos) { return path; @@ -276,21 +276,40 @@ OutputJar::~OutputJar() { // Try to perform I/O in units of this size. // (128KB is the default max request size for fuse filesystems.) -static const size_t kBufferSize = 128<<10; +static constexpr size_t kBufferSize = 128 << 10; bool OutputJar::Open() { if (file_) { diag_errx(1, "%s:%d: Cannot open output archive twice", __FILE__, __LINE__); } - // Set execute bits since we may produce an executable output file. int mode = O_CREAT | O_WRONLY | O_TRUNC; + #ifdef _WIN32 + std::wstring wpath; + std::string error; + if (!blaze_util::AsAbsoluteWindowsPath(path(), &wpath, &error)) { + diag_warn("%s:%d: AsAbsoluteWindowsPath failed: %s", __FILE__, __LINE__, + error.c_str()); + return false; + } + + HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + diag_warn("%s:%d: CreateFileW failed for %S", __FILE__, __LINE__, + wpath.c_str()); + return false; + } + // Make sure output file is in binary mode, or \r\n will be converted to \n. mode |= _O_BINARY; + int fd = _open_osfhandle(reinterpret_cast(hFile), mode); +#else + // Set execute bits since we may produce an executable output file. + int fd = open(path(), mode, 0777); #endif - int fd = open(path(), mode, 0777); if (fd < 0) { diag_warn("%s:%d: %s", __FILE__, __LINE__, path()); return false; @@ -346,7 +365,7 @@ bool OutputJar::AddJar(int jar_path_index) { bool include_entry = true; if (!options_->include_prefixes.empty()) { - for (auto& prefix : options_->include_prefixes) { + for (auto &prefix : options_->include_prefixes) { if ((include_entry = (prefix.size() <= file_name_length && 0 == strncmp(file_name, prefix.c_str(), prefix.size())))) { @@ -390,7 +409,7 @@ bool OutputJar::AddJar(int jar_path_index) { auto got = known_members_.emplace(std::string(file_name, file_name_length), EntryInfo{is_file ? nullptr : &null_combiner_, - is_file ? jar_path_index: -1}); + is_file ? jar_path_index : -1}); if (!got.second) { auto &entry_info = got.first->second; // Handle special entries (the ones that have a combiner). @@ -829,7 +848,7 @@ bool OutputJar::Close() { } { ECD64Locator *ecd64_locator = - reinterpret_cast(ReserveCdh(sizeof(ECD64Locator))); + reinterpret_cast(ReserveCdh(sizeof(ECD64Locator))); ecd64_locator->signature(); ecd64_locator->ecd64_offset(output_position + cen_size); ecd64_locator->total_disks(1); @@ -927,7 +946,7 @@ ssize_t OutputJar::AppendFile(int in_fd, off64_t offset, size_t count) { if (count == 0) { return 0; } - std::unique_ptr buffer(malloc(kBufferSize), free); + std::unique_ptr buffer(malloc(kBufferSize), free); if (buffer == nullptr) { diag_err(1, "%s:%d: malloc", __FILE__, __LINE__); } diff --git a/src/tools/singlejar/test_util.h b/src/tools/singlejar/test_util.h index fbe266173161c9..f5aacbf8e256e3 100644 --- a/src/tools/singlejar/test_util.h +++ b/src/tools/singlejar/test_util.h @@ -16,7 +16,7 @@ #include -#include "tools/cpp/runfiles/runfiles_src.h" +#include "tools/cpp/runfiles/runfiles.h" namespace singlejar_test_util { using std::string;