Index: third_party/ijar/mapped_file_unix.cc |
diff --git a/third_party/ijar/mapped_file_unix.cc b/third_party/ijar/mapped_file_unix.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f7668a517cebf35a3b16fc2b8236c27e34e76a86 |
--- /dev/null |
+++ b/third_party/ijar/mapped_file_unix.cc |
@@ -0,0 +1,147 @@ |
+// Copyright 2015 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 <errno.h> |
+#include <fcntl.h> |
+#include <stdio.h> |
+#include <unistd.h> |
+#include <sys/mman.h> |
+ |
+#include <algorithm> |
+ |
+#include "third_party/ijar/mapped_file.h" |
+ |
+#define MAX_ERROR 2048 |
+ |
+namespace devtools_ijar { |
+ |
+static char errmsg[MAX_ERROR]; |
+ |
+struct MappedInputFileImpl { |
+ size_t discarded_; |
+ int fd_; |
+}; |
+ |
+MappedInputFile::MappedInputFile(const char* name) { |
+ impl_ = NULL; |
+ opened_ = false; |
+ |
+ int fd = open(name, O_RDONLY); |
+ if (fd < 0) { |
+ snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ off_t length = lseek(fd, 0, SEEK_END); |
+ if (length < 0) { |
+ snprintf(errmsg, MAX_ERROR, "lseek(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ void* buffer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0); |
+ if (buffer == MAP_FAILED) { |
+ snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ impl_ = new MappedInputFileImpl(); |
+ impl_->fd_ = fd; |
+ impl_->discarded_ = 0; |
+ buffer_ = reinterpret_cast<u1*>(buffer); |
+ length_ = length; |
+ opened_ = true; |
+} |
+ |
+MappedInputFile::~MappedInputFile() { |
+ delete impl_; |
+} |
+ |
+void MappedInputFile::Discard(size_t bytes) { |
+ munmap(buffer_ + impl_->discarded_, bytes); |
+ impl_->discarded_ += bytes; |
+} |
+ |
+int MappedInputFile::Close() { |
+ if (close(impl_->fd_) < 0) { |
+ snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return -1; |
+ } |
+ |
+ return 0; |
+} |
+ |
+struct MappedOutputFileImpl { |
+ int fd_; |
+}; |
+ |
+MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) { |
+ impl_ = NULL; |
+ opened_ = false; |
+ int fd = open(name, O_CREAT|O_RDWR|O_TRUNC, 0644); |
+ if (fd < 0) { |
+ snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ // Create mmap-able sparse file |
+ if (ftruncate(fd, estimated_size) < 0) { |
+ snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ // Ensure that any buffer overflow in JarStripper will result in |
+ // SIGSEGV or SIGBUS by over-allocating beyond the end of the file. |
+ size_t mmap_length = std::min(estimated_size + sysconf(_SC_PAGESIZE), |
+ (u8) std::numeric_limits<size_t>::max()); |
+ void* mapped = mmap(NULL, mmap_length, PROT_WRITE, MAP_SHARED, fd, 0); |
+ if (mapped == MAP_FAILED) { |
+ snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return; |
+ } |
+ |
+ impl_ = new MappedOutputFileImpl(); |
+ impl_->fd_ = fd; |
+ buffer_ = reinterpret_cast<u1*>(mapped); |
+ opened_ = true; |
+} |
+ |
+ |
+MappedOutputFile::~MappedOutputFile() { |
+ delete impl_; |
+} |
+ |
+int MappedOutputFile::Close(int size) { |
+ if (ftruncate(impl_->fd_, size) < 0) { |
+ snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return -1; |
+ } |
+ |
+ if (close(impl_->fd_) < 0) { |
+ snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno)); |
+ errmsg_ = errmsg; |
+ return -1; |
+ } |
+ |
+ return 0; |
+} |
+ |
+} // namespace devtools_ijar |