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