|  | // 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. | 
|  |  | 
|  | #ifndef BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ | 
|  | #define BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ 1 | 
|  |  | 
|  | #include <fcntl.h> | 
|  | #include <sys/mman.h> | 
|  | #include <sys/stat.h> | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include "src/tools/singlejar/diag.h" | 
|  |  | 
|  | // The implementation is 64-bit Linux or OSX specific. | 
|  | #if !((defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)) && \ | 
|  | __SIZEOF_POINTER__ == 8) | 
|  | #error This code for 64 bit Unix. | 
|  | #endif | 
|  |  | 
|  | MappedFile::MappedFile() | 
|  | : mapped_start_(nullptr), mapped_end_(nullptr), fd_(-1) {} | 
|  |  | 
|  | 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)) < 0) { | 
|  | diag_warn("%s:%d: open %s:", __FILE__, __LINE__, path.c_str()); | 
|  | return false; | 
|  | } | 
|  | // Map the file, even if it is empty (in which case allocate 1 byte to it). | 
|  | struct stat st; | 
|  | if (fstat(fd_, &st) || | 
|  | (mapped_start_ = static_cast<unsigned char *>( | 
|  | mmap(nullptr, st.st_size ? st.st_size : 1, PROT_READ, MAP_PRIVATE, | 
|  | fd_, 0))) == MAP_FAILED) { | 
|  | if (S_ISDIR(st.st_mode)) { | 
|  | diag_warn("%s:%d: %s is a directory", __FILE__, __LINE__, path.c_str()); | 
|  | } else { | 
|  | diag_warn("%s:%d: mmap %s:", __FILE__, __LINE__, path.c_str()); | 
|  | } | 
|  | close(fd_); | 
|  | fd_ = -1; | 
|  | return false; | 
|  | } | 
|  | mapped_end_ = mapped_start_ + st.st_size; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void MappedFile::Close() { | 
|  | if (is_open()) { | 
|  | munmap(mapped_start_, mapped_end_ - mapped_start_); | 
|  | mapped_start_ = mapped_end_ = nullptr; | 
|  | close(fd_); | 
|  | fd_ = -1; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool MappedFile::is_open() const { return fd_ >= 0; } | 
|  |  | 
|  | #endif  // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ |