/* * Map a file (from fd's current offset) into a private, read-write memory * segment that will be marked read-only (a/k/a "writable read-only"). The * file offset must be a multiple of the system page size. * * In some cases the mapping will be fully writable (e.g. for files on * FAT filesystems). * * On success, returns 0 and fills out "pMap". On failure, returns a nonzero * value and does not disturb "pMap". */ int sysMapFileInShmemWritableReadOnly(int fd, MemMapping* pMap) { #ifdef HAVE_POSIX_FILEMAP off_t start; size_t length; void* memPtr; assert(pMap != NULL); if (getFileStartAndLength(fd, &start, &length) < 0) return -1; memPtr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, start); if (memPtr == MAP_FAILED) { ALOGW("mmap(%d, R/W, FILE|PRIVATE, %d, %d) failed: %s", (int) length, fd, (int) start, strerror(errno)); return -1; } if (mprotect(memPtr, length, PROT_READ) < 0) { /* this fails with EACCESS on FAT filesystems, e.g. /sdcard */ int err = errno; ALOGV("mprotect(%p, %d, PROT_READ) failed: %s", memPtr, length, strerror(err)); ALOGD("mprotect(RO) failed (%d), file will remain read-write", err); } pMap->baseAddr = pMap->addr = memPtr; pMap->baseLength = pMap->length = length; return 0; #else return sysFakeMapFile(fd, pMap); #endif }
/* * Map a file (from fd's current offset) into a shared, read-only memory * segment. The file offset must be a multiple of the system page size. * * On success, returns 0 and fills out "pMap". On failure, returns a nonzero * value and does not disturb "pMap". */ int sysMapFileInShmemReadOnly(int fd, MemMapping* pMap) { #ifdef HAVE_POSIX_FILEMAP off_t start; size_t length; void* memPtr; assert(pMap != NULL); if (getFileStartAndLength(fd, &start, &length) < 0) return -1; memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start); if (memPtr == MAP_FAILED) { ALOGW("mmap(%d, RO, FILE|SHARED, %d, %d) failed: %s", (int) length, fd, (int) start, strerror(errno)); return -1; } pMap->baseAddr = pMap->addr = memPtr; pMap->baseLength = pMap->length = length; return 0; #else return sysFakeMapFile(fd, pMap); #endif }