1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SkMMapStream.h" 9 10 #include <unistd.h> 11 #include <sys/mman.h> 12 #include <fcntl.h> 13 #include <errno.h> 14 15 SkMMAPStream::SkMMAPStream(const char filename[]) 16 { 17 fAddr = NULL; // initialize to failure case 18 19 int fildes = open(filename, O_RDONLY); 20 if (fildes < 0) 21 { 22 SkDEBUGF(("---- failed to open(%s) for mmap stream error=%d\n", filename, errno)); 23 return; 24 } 25 26 off_t offset = lseek(fildes, 0, SEEK_END); // find the file size 27 if (offset == -1) 28 { 29 SkDEBUGF(("---- failed to lseek(%s) for mmap stream error=%d\n", filename, errno)); 30 close(fildes); 31 return; 32 } 33 (void)lseek(fildes, 0, SEEK_SET); // restore file offset to beginning 34 35 // to avoid a 64bit->32bit warning, I explicitly create a size_t size 36 size_t size = static_cast<size_t>(offset); 37 38 void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fildes, 0); 39 40 // According to the POSIX documentation of mmap it adds an extra reference 41 // to the file associated with the fildes which is not removed by a 42 // subsequent close() on that fildes. This reference is removed when there 43 // are no more mappings to the file. 44 close(fildes); 45 46 if (MAP_FAILED == addr) 47 { 48 SkDEBUGF(("---- failed to mmap(%s) for mmap stream error=%d\n", filename, errno)); 49 return; 50 } 51 52 this->INHERITED::setMemory(addr, size); 53 54 fAddr = addr; 55 fSize = size; 56 } 57 58 SkMMAPStream::~SkMMAPStream() 59 { 60 this->closeMMap(); 61 } 62 63 void SkMMAPStream::setMemory(const void* data, size_t length, bool copyData) 64 { 65 this->closeMMap(); 66 this->INHERITED::setMemory(data, length, copyData); 67 } 68 69 void SkMMAPStream::closeMMap() 70 { 71 if (fAddr) 72 { 73 munmap(fAddr, fSize); 74 fAddr = NULL; 75 } 76 } 77 78