aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Loo Rong Jie <loorongjie@gmail.com>2018-08-08 22:52:58 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-08 22:54:22 -0700
commit27385b1acfbecb815862762337ba1cdde7237576 (patch)
tree6a5e535af555ce157f6e259521f7e480ae07fb9a /src
parentc535ac28697d49f436a70f3aa7f1d1e938db5d3c (diff)
[singlejar] Port mapped_file for Windows
`src/tools/singlejar/mapped_file_*.inc` are now included in `src/tools/singlejar/mapped_file.cc` instead of header file and no longer inline most member functions: these functions are too large for inlining. /cc @laszlocsomor Closes #5780. PiperOrigin-RevId: 207998444
Diffstat (limited to 'src')
-rw-r--r--src/tools/singlejar/BUILD8
-rw-r--r--src/tools/singlejar/mapped_file.cc21
-rw-r--r--src/tools/singlejar/mapped_file.h25
-rw-r--r--src/tools/singlejar/mapped_file_posix.inc8
-rw-r--r--src/tools/singlejar/mapped_file_windows.inc101
-rw-r--r--src/tools/singlejar/output_jar.cc4
6 files changed, 129 insertions, 38 deletions
diff --git a/src/tools/singlejar/BUILD b/src/tools/singlejar/BUILD
index 01415cccbb..2f0164dd0e 100644
--- a/src/tools/singlejar/BUILD
+++ b/src/tools/singlejar/BUILD
@@ -24,6 +24,7 @@ filegroup(
"diag.h",
"input_jar.cc",
"input_jar.h",
+ "mapped_file.cc",
"mapped_file.h",
"mapped_file_posix.inc",
"mapped_file_windows.inc",
@@ -348,13 +349,16 @@ cc_library(
cc_library(
name = "mapped_file",
- srcs = select({
+ srcs = ["mapped_file.cc"] + select({
"//src:windows": ["mapped_file_windows.inc"],
"//conditions:default": ["mapped_file_posix.inc"],
}),
hdrs = ["mapped_file.h"],
visibility = ["//visibility:private"],
- deps = [":diag"],
+ deps = [
+ ":diag",
+ ":port",
+ ],
)
cc_library(
diff --git a/src/tools/singlejar/mapped_file.cc b/src/tools/singlejar/mapped_file.cc
new file mode 100644
index 0000000000..98aca74674
--- /dev/null
+++ b/src/tools/singlejar/mapped_file.cc
@@ -0,0 +1,21 @@
+// Copyright 2018 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/mapped_file.h"
+
+#ifdef _WIN32
+#include "src/tools/singlejar/mapped_file_windows.inc"
+#else // not _WIN32
+#include "src/tools/singlejar/mapped_file_posix.inc"
+#endif // _WIN32
diff --git a/src/tools/singlejar/mapped_file.h b/src/tools/singlejar/mapped_file.h
index f4ada45a2b..bca19bc18d 100644
--- a/src/tools/singlejar/mapped_file.h
+++ b/src/tools/singlejar/mapped_file.h
@@ -17,6 +17,8 @@
#include <string>
+#include "src/tools/singlejar/port.h"
+
/*
* A mapped read-only file with auto closing.
*
@@ -28,12 +30,6 @@
*/
class MappedFile {
public:
-#ifdef _WIN32
- typedef /* HANDLE = void* */ void *FileHandleType;
-#else // not _WIN32
- typedef int FileHandleType;
-#endif // _WIN32
-
MappedFile();
~MappedFile() { Close(); }
@@ -51,23 +47,20 @@ class MappedFile {
const unsigned char *address(off_t offset) const {
return mapped_start_ + offset;
}
- off_t offset(const void *address) const {
+ off64_t offset(const void *address) const {
return reinterpret_cast<const unsigned char *>(address) - mapped_start_;
}
- FileHandleType fd() const { return fd_; }
+ int fd() const { return fd_; }
size_t size() const { return mapped_end_ - mapped_start_; }
- bool is_open() const;
+ bool is_open() const { return fd_ >= 0; }
private:
unsigned char *mapped_start_;
unsigned char *mapped_end_;
- FileHandleType fd_;
-};
-
+ int fd_;
#ifdef _WIN32
-#include "src/tools/singlejar/mapped_file_windows.inc"
-#else // not _WIN32
-#include "src/tools/singlejar/mapped_file_posix.inc"
-#endif // _WIN32
+ /* HANDLE */ void *hMapFile_;
+#endif
+};
#endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_H_
diff --git a/src/tools/singlejar/mapped_file_posix.inc b/src/tools/singlejar/mapped_file_posix.inc
index ad6c6a5310..637661b719 100644
--- a/src/tools/singlejar/mapped_file_posix.inc
+++ b/src/tools/singlejar/mapped_file_posix.inc
@@ -30,10 +30,10 @@
#error This code for 64 bit Unix.
#endif
-inline MappedFile::MappedFile()
+MappedFile::MappedFile()
: mapped_start_(nullptr), mapped_end_(nullptr), fd_(-1) {}
-inline bool MappedFile::Open(const std::string& path) {
+bool MappedFile::Open(const std::string& path) {
if (is_open()) {
diag_errx(1, "%s:%d: This instance is already open", __FILE__, __LINE__);
}
@@ -60,7 +60,7 @@ inline bool MappedFile::Open(const std::string& path) {
return true;
}
-inline void MappedFile::Close() {
+void MappedFile::Close() {
if (is_open()) {
munmap(mapped_start_, mapped_end_ - mapped_start_);
mapped_start_ = mapped_end_ = nullptr;
@@ -69,6 +69,4 @@ inline void MappedFile::Close() {
}
}
-inline 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 366103f57a..43e524ae12 100644
--- a/src/tools/singlejar/mapped_file_windows.inc
+++ b/src/tools/singlejar/mapped_file_windows.inc
@@ -19,30 +19,101 @@
#error This code is for 64 bit Windows.
#endif
+#include "src/tools/singlejar/diag.h"
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
#include <windows.h>
#include <string>
-typedef HANDLE FileHandleType;
+MappedFile::MappedFile()
+ : mapped_start_(nullptr),
+ mapped_end_(nullptr),
+ fd_(-1),
+ hMapFile_(INVALID_HANDLE_VALUE) {}
-inline MappedFile::MappedFile()
- : mapped_start_(nullptr), mapped_end_(nullptr), fd_(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());
+ return false;
+ }
-inline bool MappedFile::Open(const std::string& path) {
- // TODO(laszlocsomor): implement as part of
- // https://github.com/bazelbuild/bazel/issues/2241
- return false;
-}
+ HANDLE hFile = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
+ LARGE_INTEGER temp;
+ ::GetFileSizeEx(hFile, &temp);
+ size_t fileSize = temp.QuadPart;
+
+ if (fileSize == 0) {
+ // This is where Windows implementation differs from POSIX's.
+ // CreateFileMapping cannot map empty file:
+ //
+ // From
+ // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createfilemappinga
+ //
+ // An attempt to map a file with a length of 0 (zero) fails with an error
+ // code of ERROR_FILE_INVALID. Applications should test for files with a
+ // length of 0 (zero) and reject those files.
+ //
+ // Since the test at //src/tools/singlerjar/input_jar_bad_jar_test expects
+ // empty file to fail anyway, returning error here shouldn't be a problem.
+ diag_warn("%s:%d: Windows MappedFile cannot handle empty file (%s)",
+ __FILE__, __LINE__, path.c_str());
+ _close(fd_);
+ fd_ = -1;
+ return false;
+ }
+
+ hMapFile_ = ::CreateFileMapping(
+ hFile,
+ nullptr, // default security
+ PAGE_READONLY, // read-only permission
+ static_cast<DWORD>(fileSize >> 32), // size of mapping object, high
+ static_cast<DWORD>(fileSize), // size of mapping object, low
+ nullptr); // name of mapping object
+
+ if (hMapFile_ == nullptr) {
+ diag_warn("%s:%d: CreateFileMapping for %s failed", __FILE__, __LINE__,
+ path.c_str());
+ _close(fd_);
+ fd_ = -1;
+ return false;
+ }
+
+ mapped_start_ = static_cast<unsigned char*>(
+ MapViewOfFile(hMapFile_,
+ FILE_MAP_READ | FILE_MAP_COPY, // PROT_READ | MAP_PRIVATE
+ 0, // file offset, high
+ 0, // file offset, low
+ fileSize)); // file size
+ if (mapped_start_ == nullptr) {
+ diag_warn("%s:%d: MapViewOfFile for %s failed", __FILE__, __LINE__,
+ path.c_str());
+ ::CloseHandle(hMapFile_);
+ _close(fd_);
+ hMapFile_ = INVALID_HANDLE_VALUE;
+ fd_ = -1;
+ return false;
+ }
-inline void MappedFile::Close() {
- // TODO(laszlocsomor): implement as part of
- // https://github.com/bazelbuild/bazel/issues/2241
+ mapped_end_ = mapped_start_ + fileSize;
+ return true;
}
-inline bool MappedFile::is_open() const {
- // TODO(laszlocsomor): implement as part of
- // https://github.com/bazelbuild/bazel/issues/2241
- return false;
+void MappedFile::Close() {
+ if (is_open()) {
+ ::UnmapViewOfFile(mapped_start_);
+ ::CloseHandle(hMapFile_);
+ _close(fd_);
+ hMapFile_ = INVALID_HANDLE_VALUE;
+ fd_ = -1;
+ mapped_start_ = mapped_end_ = nullptr;
+ }
}
#endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_WINDOWS_H_ \ No newline at end of file
diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc
index 5b6d24fc6b..923894698d 100644
--- a/src/tools/singlejar/output_jar.cc
+++ b/src/tools/singlejar/output_jar.cc
@@ -24,6 +24,10 @@
#include <sys/stat.h>
#include <time.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
#include "src/tools/singlejar/combiners.h"
#include "src/tools/singlejar/diag.h"
#include "src/tools/singlejar/input_jar.h"