18339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine/* Copyright (C) 2007-2010 The Android Open Source Project 28339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** 38339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** This software is licensed under the terms of the GNU General Public 48339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and 58339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** may be copied, distributed, and modified under those terms. 68339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** 78339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** This program is distributed in the hope that it will be useful, 88339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of 98339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine** GNU General Public License for more details. 118339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine*/ 128339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 138339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine/* 148339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine * Contains implementation of routines that implement platform-independent 158339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine * file I/O. 168339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine */ 178339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 18af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner#include "android/utils/mapfile.h" 19af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner 208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "stddef.h" 218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "sys/types.h" 228339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "errno.h" 238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 24aea1b87e31b952a733fe6cc6a0be4493a78ea961Raphael#include "windows.h" 258339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <sys/mman.h> 278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <sys/stat.h> 298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <fcntl.h> 308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <unistd.h> 318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 32af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner#include "android/utils/eintr_wrapper.h" 338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 348339d18223eed408bfefcd00f649a2b13ccac52cVladimir ChtchetkineMapFile* 358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_open(const char* path, int oflag, int share_mode) 368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 378339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 388339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine DWORD win32_share; 394e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner DWORD win32_desired_access = GENERIC_READ; 404e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner DWORD win32_disposition = OPEN_EXISTING; 418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine DWORD win32_flags; 428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 438339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Convert to Win32 desired access. */ 448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((oflag & O_RDWR) == O_RDWR) { 458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_desired_access = GENERIC_READ | GENERIC_WRITE; 468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else if ((oflag & O_ACCMODE) == O_RDONLY) { 478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_desired_access = GENERIC_READ; 488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else if ((oflag & O_WRONLY) == O_WRONLY) { 498339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_desired_access = GENERIC_WRITE; 508339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 518339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 528339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Convert to Win32 sharing. */ 538339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_share = 0; 548339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((share_mode & S_IWRITE) != 0) { 558339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_share |= FILE_SHARE_WRITE; 568339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 578339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((share_mode & S_IREAD) != 0) { 588339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_share |= FILE_SHARE_READ; 598339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 608339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 618339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Convert to Win32 disposition. */ 628339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((oflag & O_CREAT) == O_CREAT) { 638339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((oflag & O_EXCL) == O_EXCL) { 648339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_disposition = CREATE_NEW; 658339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else { 668339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_disposition = OPEN_ALWAYS; 678339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 688339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } if ((oflag & O_TRUNC) == O_TRUNC) { 698339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_desired_access = TRUNCATE_EXISTING; 708339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else { 718339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_disposition = OPEN_EXISTING; 728339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 738339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 748339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Convert to Win32 flags. */ 758339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_flags = 0; 768339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#if defined(O_DSYNC) 778339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((oflag & O_DSYNC) == O_DSYNC || 788339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine (oflag & O_RSYNC) == O_RSYNC || 798339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine (oflag & O_RSYNC) == O_SYNC) { 808339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_flags |= FILE_FLAG_WRITE_THROUGH; 818339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 828339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // O_DSYNC 838339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 848339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine HANDLE file_handle = CreateFile(path, win32_desired_access, win32_share, 858339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine NULL, win32_disposition, win32_flags, NULL); 868339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (file_handle == INVALID_HANDLE_VALUE) { 878339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 888339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 898339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 908339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine int file_handle = open(path, oflag, share_mode); 918339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 928339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 93d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner return (MapFile*)(ptrdiff_t)file_handle; 948339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 958339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 968339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkineint 978339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_close(MapFile* handle) 988339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 998339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 1008339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (CloseHandle(handle)) { 1018339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return 0; 1028339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else { 1038339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 1048339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return -1; 1058339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 1068339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 107d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner return close((int)(ptrdiff_t)handle); 1088339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 1098339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 1108339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1118339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinessize_t 1128339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_read(MapFile* handle, void* buf, size_t nbyte) 1138339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 1148339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 1158339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine ssize_t ret_bytes; 1168339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine DWORD read_bytes; 1178339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (ReadFile(handle, buf, nbyte, &read_bytes, NULL)) { 1188339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine ret_bytes = (ssize_t)read_bytes; 1198339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else { 1208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 1218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine ret_bytes = -1; 1228339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 1238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return ret_bytes; 1248339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 125af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner return HANDLE_EINTR(read((int)(ptrdiff_t)handle, buf, nbyte)); 1268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 1278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 1288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinessize_t 1308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_read_at(MapFile* handle, size_t offset, void* buf, size_t nbyte) 1318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 1328339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 1338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine LARGE_INTEGER convert; 1348339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine convert.QuadPart = offset; 1358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((SetFilePointer(handle, convert.LowPart, &convert.HighPart, 1368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine FILE_BEGIN) == INVALID_SET_FILE_POINTER) && 1378339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine (GetLastError() != NO_ERROR)) { 1388339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 1398339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return -1; 1408339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 1418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return mapfile_read(handle, buf, nbyte); 1428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 143d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner ssize_t res = lseek((int)(ptrdiff_t)handle, offset, SEEK_SET); 1448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return res >= 0 ? mapfile_read(handle, buf, nbyte) : res; 1458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 1468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 1478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinevoid* 1498339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_map(MapFile* handle, 1508339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t offset, 1518339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t size, 1528339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine int prot, 1538339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine void** mapped_offset, 1548339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t* mapped_size) 1558339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 1568339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine void* mapped_at = NULL; 1578339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t align_mask; 1588339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t map_offset; 1598339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine size_t map_size; 1608339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1618339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Get the mask for mapping offset alignment. */ 1628339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 1638339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine DWORD win32_prot; 1648339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine DWORD win32_map; 1658339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine HANDLE map_handle; 1668339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine LARGE_INTEGER converter; 1678339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine SYSTEM_INFO sys_info; 1688339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine GetSystemInfo(&sys_info); 1698339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine align_mask = sys_info.dwAllocationGranularity - 1; 1708339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 1718339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine align_mask = getpagesize() - 1; 1728339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 1738339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1748339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Adjust mapping offset and mapping size accordingly to 1758339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine * the mapping alignment requirements. */ 1768339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine map_offset = offset & ~align_mask; 1778339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine map_size = (size_t)(offset - map_offset + size); 1788339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1798339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Make sure mapping size doesn't exceed 4G. */ 1808339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (map_size < size) { 1818339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = EFBIG; 1828339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return NULL; 1838339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 1848339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 1858339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Map the section. */ 1868339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 1878339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Convert to Win32 page protection and mapping type. */ 1888339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_prot = PAGE_READONLY; 1898339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_map = FILE_MAP_READ; 1908339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (prot != PROT_NONE) { 1918339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if ((prot & (PROT_WRITE | PROT_EXEC)) == 0) { 1928339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_prot = PAGE_READONLY; 1938339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_map = FILE_MAP_READ; 1948339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else if ((prot & (PROT_WRITE | PROT_EXEC)) == 1958339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine (PROT_WRITE | PROT_EXEC)) { 1968339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_prot = PAGE_EXECUTE_READWRITE; 1978339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_map = FILE_MAP_WRITE; 1988339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else if ((prot & PROT_WRITE) == PROT_WRITE) { 1998339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_prot = PAGE_READWRITE; 2008339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_map = FILE_MAP_WRITE; 2018339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } else if ((prot & PROT_EXEC) == PROT_EXEC) { 2028339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_prot = PAGE_EXECUTE_READ; 2038339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine win32_map = FILE_MAP_READ; 2048339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2058339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2068339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 2078339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine converter.QuadPart = map_offset + map_size; 2088339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine map_handle = CreateFileMapping(handle, NULL, win32_prot, 2098339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine converter.HighPart, converter.LowPart, NULL); 2108339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (map_handle != NULL) { 2118339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine converter.QuadPart = map_offset; 2128339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine mapped_at = MapViewOfFile(map_handle, win32_map, converter.HighPart, 2138339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine converter.LowPart, map_size); 2148339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine /* Memory mapping (if successful) will hold extra references to the 2158339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine * mapping, so we can close it right after we mapped file view. */ 2168339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine CloseHandle(map_handle); 2178339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2188339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (mapped_at == NULL) { 2198339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 2208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return NULL; 2218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2228339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 2238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine mapped_at = 224d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner mmap(0, map_size, PROT_READ, MAP_SHARED, (int)(ptrdiff_t)handle, map_offset); 2258339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (mapped_at == MAP_FAILED) { 2268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return NULL; 2278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 2298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 2308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine *mapped_offset = (char*)mapped_at + (offset - map_offset); 2318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine *mapped_size = size; 2328339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 2338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return mapped_at; 2348339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 2358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine 2368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkineint 2378339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_unmap(void* mapped_at, size_t len) 2388339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{ 2398339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32 2408339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine if (!UnmapViewOfFile(mapped_at)) { 2418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine errno = GetLastError(); 2428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return -1; 2438339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine } 2448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return 0; 2458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else // WIN32 2468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine return munmap(mapped_at, len); 2478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif // WIN32 2488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine} 249