OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Bazel Authors. All rights reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #include <errno.h> |
| 16 #include <fcntl.h> |
| 17 #include <stdio.h> |
| 18 #include <unistd.h> |
| 19 #include <sys/mman.h> |
| 20 |
| 21 #include <algorithm> |
| 22 |
| 23 #include "third_party/ijar/mapped_file.h" |
| 24 |
| 25 #define MAX_ERROR 2048 |
| 26 |
| 27 namespace devtools_ijar { |
| 28 |
| 29 static char errmsg[MAX_ERROR]; |
| 30 |
| 31 struct MappedInputFileImpl { |
| 32 size_t discarded_; |
| 33 int fd_; |
| 34 }; |
| 35 |
| 36 MappedInputFile::MappedInputFile(const char* name) { |
| 37 impl_ = NULL; |
| 38 opened_ = false; |
| 39 |
| 40 int fd = open(name, O_RDONLY); |
| 41 if (fd < 0) { |
| 42 snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno)); |
| 43 errmsg_ = errmsg; |
| 44 return; |
| 45 } |
| 46 |
| 47 off_t length = lseek(fd, 0, SEEK_END); |
| 48 if (length < 0) { |
| 49 snprintf(errmsg, MAX_ERROR, "lseek(): %s", strerror(errno)); |
| 50 errmsg_ = errmsg; |
| 51 return; |
| 52 } |
| 53 |
| 54 void* buffer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0); |
| 55 if (buffer == MAP_FAILED) { |
| 56 snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno)); |
| 57 errmsg_ = errmsg; |
| 58 return; |
| 59 } |
| 60 |
| 61 impl_ = new MappedInputFileImpl(); |
| 62 impl_->fd_ = fd; |
| 63 impl_->discarded_ = 0; |
| 64 buffer_ = reinterpret_cast<u1*>(buffer); |
| 65 length_ = length; |
| 66 opened_ = true; |
| 67 } |
| 68 |
| 69 MappedInputFile::~MappedInputFile() { |
| 70 delete impl_; |
| 71 } |
| 72 |
| 73 void MappedInputFile::Discard(size_t bytes) { |
| 74 munmap(buffer_ + impl_->discarded_, bytes); |
| 75 impl_->discarded_ += bytes; |
| 76 } |
| 77 |
| 78 int MappedInputFile::Close() { |
| 79 if (close(impl_->fd_) < 0) { |
| 80 snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno)); |
| 81 errmsg_ = errmsg; |
| 82 return -1; |
| 83 } |
| 84 |
| 85 return 0; |
| 86 } |
| 87 |
| 88 struct MappedOutputFileImpl { |
| 89 int fd_; |
| 90 }; |
| 91 |
| 92 MappedOutputFile::MappedOutputFile(const char* name, u8 estimated_size) { |
| 93 impl_ = NULL; |
| 94 opened_ = false; |
| 95 int fd = open(name, O_CREAT|O_RDWR|O_TRUNC, 0644); |
| 96 if (fd < 0) { |
| 97 snprintf(errmsg, MAX_ERROR, "open(): %s", strerror(errno)); |
| 98 errmsg_ = errmsg; |
| 99 return; |
| 100 } |
| 101 |
| 102 // Create mmap-able sparse file |
| 103 if (ftruncate(fd, estimated_size) < 0) { |
| 104 snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno)); |
| 105 errmsg_ = errmsg; |
| 106 return; |
| 107 } |
| 108 |
| 109 // Ensure that any buffer overflow in JarStripper will result in |
| 110 // SIGSEGV or SIGBUS by over-allocating beyond the end of the file. |
| 111 size_t mmap_length = std::min(estimated_size + sysconf(_SC_PAGESIZE), |
| 112 (u8) std::numeric_limits<size_t>::max()); |
| 113 void* mapped = mmap(NULL, mmap_length, PROT_WRITE, MAP_SHARED, fd, 0); |
| 114 if (mapped == MAP_FAILED) { |
| 115 snprintf(errmsg, MAX_ERROR, "mmap(): %s", strerror(errno)); |
| 116 errmsg_ = errmsg; |
| 117 return; |
| 118 } |
| 119 |
| 120 impl_ = new MappedOutputFileImpl(); |
| 121 impl_->fd_ = fd; |
| 122 buffer_ = reinterpret_cast<u1*>(mapped); |
| 123 opened_ = true; |
| 124 } |
| 125 |
| 126 |
| 127 MappedOutputFile::~MappedOutputFile() { |
| 128 delete impl_; |
| 129 } |
| 130 |
| 131 int MappedOutputFile::Close(int size) { |
| 132 if (ftruncate(impl_->fd_, size) < 0) { |
| 133 snprintf(errmsg, MAX_ERROR, "ftruncate(): %s", strerror(errno)); |
| 134 errmsg_ = errmsg; |
| 135 return -1; |
| 136 } |
| 137 |
| 138 if (close(impl_->fd_) < 0) { |
| 139 snprintf(errmsg, MAX_ERROR, "close(): %s", strerror(errno)); |
| 140 errmsg_ = errmsg; |
| 141 return -1; |
| 142 } |
| 143 |
| 144 return 0; |
| 145 } |
| 146 |
| 147 } // namespace devtools_ijar |
OLD | NEW |