| /* |
| * Copyright (C) 2017-2020 The Project X-Ray Authors. |
| * |
| * Use of this source code is governed by a ISC-style |
| * license that can be found in the LICENSE file or at |
| * https://opensource.org/licenses/ISC |
| * |
| * SPDX-License-Identifier: ISC |
| */ |
| #include <prjxray/memory_mapped_file.h> |
| |
| #include <fcntl.h> |
| #include <sys/mman.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| |
| namespace prjxray { |
| |
| std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile( |
| const std::string& path) { |
| int fd = open(path.c_str(), O_RDONLY, 0); |
| if (fd == -1) |
| return nullptr; |
| |
| struct stat statbuf; |
| if (fstat(fd, &statbuf) < 0) { |
| close(fd); |
| return nullptr; |
| } |
| |
| // mmap() will fail with EINVAL if length==0. If this file is |
| // zero-length, return an object (to indicate the file exists) but |
| // load it with a nullptr and zero length. |
| if (statbuf.st_size == 0) { |
| close(fd); |
| return std::unique_ptr<MemoryMappedFile>( |
| new MemoryMappedFile(nullptr, 0)); |
| } |
| |
| void* file_map = |
| mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
| |
| // If mmap() succeeded, the fd is no longer needed as the mapping will |
| // keep the file open. If mmap() failed, the fd needs to be closed |
| // anyway. |
| close(fd); |
| |
| if (file_map == MAP_FAILED) |
| return nullptr; |
| |
| return std::unique_ptr<MemoryMappedFile>( |
| new MemoryMappedFile(file_map, statbuf.st_size)); |
| } |
| |
| MemoryMappedFile::~MemoryMappedFile() { |
| munmap(data_, size_); |
| } |
| |
| } // namespace prjxray |