Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[singlejar] Fix Windows long path issue #6992

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/tools/singlejar/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ cc_library(
deps = [
":diag",
":port",
"//src/main/cpp/util",
],
)

Expand Down Expand Up @@ -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",
],
)
Expand Down
2 changes: 1 addition & 1 deletion src/tools/singlejar/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <string.h>
#include <windows.h>
#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__); \
Expand Down
2 changes: 0 additions & 2 deletions src/tools/singlejar/input_jar.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class InputJar {

~InputJar() { Close(); }

int fd() const { return mapped_file_.fd(); }
rongjiecomputer marked this conversation as resolved.
Show resolved Hide resolved

// Opens the file, memory maps it and locates Central Directory.
bool Open(const std::string& path);

Expand Down
7 changes: 4 additions & 3 deletions src/tools/singlejar/mapped_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,17 @@ class MappedFile {
off64_t offset(const void *address) const {
return reinterpret_cast<const unsigned char *>(address) - mapped_start_;
}
int fd() const { return fd_; }
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
};

Expand Down
2 changes: 2 additions & 0 deletions src/tools/singlejar/mapped_file_posix.inc
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ void MappedFile::Close() {
}
}

bool MappedFile::is_open() const { return fd_ >= 0; }

#endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_
38 changes: 26 additions & 12 deletions src/tools/singlejar/mapped_file_windows.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<HANDLE>(_get_osfhandle(fd_));
LARGE_INTEGER temp;
::GetFileSizeEx(hFile, &temp);
::GetFileSizeEx(hFile_, &temp);
size_t fileSize = temp.QuadPart;

if (fileSize == 0) {
Expand All @@ -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<DWORD>(fileSize >> 32), // size of mapping object, high
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}
}
Expand Down
35 changes: 27 additions & 8 deletions src/tools/singlejar/output_jar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<intptr_t>(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;
Expand Down Expand Up @@ -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())))) {
Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -829,7 +848,7 @@ bool OutputJar::Close() {
}
{
ECD64Locator *ecd64_locator =
reinterpret_cast<ECD64Locator *>(ReserveCdh(sizeof(ECD64Locator)));
reinterpret_cast<ECD64Locator *>(ReserveCdh(sizeof(ECD64Locator)));
ecd64_locator->signature();
ecd64_locator->ecd64_offset(output_position + cen_size);
ecd64_locator->total_disks(1);
Expand Down Expand Up @@ -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<void, decltype(free)*> buffer(malloc(kBufferSize), free);
std::unique_ptr<void, decltype(free) *> buffer(malloc(kBufferSize), free);
if (buffer == nullptr) {
diag_err(1, "%s:%d: malloc", __FILE__, __LINE__);
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/singlejar/test_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#include <string>

#include "tools/cpp/runfiles/runfiles_src.h"
#include "tools/cpp/runfiles/runfiles.h"

namespace singlejar_test_util {
using std::string;
Expand Down