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