mapfile.c revision 4e024bb4f5c8aa8b07459f7fbd65c35122127fd1
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
188339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "stddef.h"
198339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "sys/types.h"
208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "errno.h"
218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef  WIN32
22aea1b87e31b952a733fe6cc6a0be4493a78ea961Raphael#include "windows.h"
238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
248339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <sys/mman.h>
258339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <sys/stat.h>
278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <fcntl.h>
288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include <unistd.h>
298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#include "mapfile.h"
318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
328339d18223eed408bfefcd00f649a2b13ccac52cVladimir ChtchetkineMapFile*
338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_open(const char* path, int oflag, int share_mode)
348339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32
368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    DWORD win32_share;
374e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    DWORD win32_desired_access = GENERIC_READ;
384e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    DWORD win32_disposition = OPEN_EXISTING;
398339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    DWORD win32_flags;
408339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Convert to Win32 desired access. */
428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((oflag & O_RDWR) == O_RDWR) {
438339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_desired_access = GENERIC_READ | GENERIC_WRITE;
448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } else if ((oflag & O_ACCMODE) == O_RDONLY) {
458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_desired_access = GENERIC_READ;
468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } else if ((oflag & O_WRONLY) == O_WRONLY) {
478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_desired_access = GENERIC_WRITE;
488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
498339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
508339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Convert to Win32 sharing. */
518339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    win32_share = 0;
528339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((share_mode & S_IWRITE) != 0) {
538339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_share |= FILE_SHARE_WRITE;
548339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
558339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((share_mode & S_IREAD) != 0) {
568339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_share |= FILE_SHARE_READ;
578339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
588339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
598339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Convert to Win32 disposition. */
608339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((oflag & O_CREAT) == O_CREAT) {
618339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        if ((oflag & O_EXCL) == O_EXCL) {
628339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_disposition = CREATE_NEW;
638339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        } else {
648339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_disposition = OPEN_ALWAYS;
658339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        }
668339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } if ((oflag & O_TRUNC) == O_TRUNC) {
678339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_desired_access = TRUNCATE_EXISTING;
688339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } else {
698339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_disposition = OPEN_EXISTING;
708339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
718339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
728339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Convert to Win32 flags. */
738339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    win32_flags = 0;
748339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#if defined(O_DSYNC)
758339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((oflag & O_DSYNC) == O_DSYNC ||
768339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        (oflag & O_RSYNC) == O_RSYNC ||
778339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        (oflag & O_RSYNC) == O_SYNC) {
788339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        win32_flags |= FILE_FLAG_WRITE_THROUGH;
798339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
808339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // O_DSYNC
818339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
828339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    HANDLE file_handle = CreateFile(path, win32_desired_access, win32_share,
838339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine                                    NULL, win32_disposition, win32_flags, NULL);
848339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (file_handle == INVALID_HANDLE_VALUE) {
858339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
868339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
878339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
888339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    int file_handle = open(path, oflag, share_mode);
898339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
908339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
918339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return (MapFile*)file_handle;
928339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
938339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
948339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkineint
958339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_close(MapFile* handle)
968339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
978339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32
988339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (CloseHandle(handle)) {
998339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return 0;
1008339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } else {
1018339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
1028339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return -1;
1038339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
1048339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
1058339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return close((int)handle);
1068339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
1078339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
1088339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1098339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinessize_t
1108339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_read(MapFile* handle, void* buf, size_t nbyte)
1118339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
1128339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32
1138339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    ssize_t ret_bytes;
1148339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    DWORD read_bytes;
1158339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (ReadFile(handle, buf, nbyte, &read_bytes, NULL)) {
1168339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        ret_bytes = (ssize_t)read_bytes;
1178339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } else {
1188339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
1198339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        ret_bytes = -1;
1208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
1218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return ret_bytes;
1228339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
1238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    ssize_t ret;
1248339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    do {
1258339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        ret = read((int)handle, buf, nbyte);
1268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    } while (ret < 0 && errno == EINTR);
1278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return ret;
1288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
1298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
1308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinessize_t
1328339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_read_at(MapFile* handle, size_t offset, void* buf, size_t nbyte)
1338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
1348339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32
1358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    LARGE_INTEGER convert;
1368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    convert.QuadPart = offset;
1378339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if ((SetFilePointer(handle, convert.LowPart, &convert.HighPart,
1388339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine                        FILE_BEGIN) == INVALID_SET_FILE_POINTER) &&
1398339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            (GetLastError() != NO_ERROR)) {
1408339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
1418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return -1;
1428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
1438339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return mapfile_read(handle, buf, nbyte);
1448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
1458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    ssize_t res = lseek((int)handle, offset, SEEK_SET);
1468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return res >= 0 ? mapfile_read(handle, buf, nbyte) : res;
1478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
1488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
1498339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1508339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinevoid*
1518339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_map(MapFile* handle,
1528339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            size_t offset,
1538339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            size_t size,
1548339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            int prot,
1558339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            void** mapped_offset,
1568339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            size_t* mapped_size)
1578339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
1588339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    void* mapped_at = NULL;
1598339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    size_t align_mask;
1608339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    size_t map_offset;
1618339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    size_t map_size;
1628339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1638339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine  /* Get the mask for mapping offset alignment. */
1648339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef  WIN32
1658339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    DWORD win32_prot;
1668339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    DWORD win32_map;
1678339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    HANDLE map_handle;
1688339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    LARGE_INTEGER converter;
1698339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    SYSTEM_INFO sys_info;
1708339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    GetSystemInfo(&sys_info);
1718339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    align_mask = sys_info.dwAllocationGranularity - 1;
1728339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
1738339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    align_mask = getpagesize() - 1;
1748339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
1758339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1768339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Adjust mapping offset and mapping size accordingly to
1778339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine     * the mapping alignment requirements. */
1788339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    map_offset = offset & ~align_mask;
1798339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    map_size = (size_t)(offset - map_offset + size);
1808339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1818339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Make sure mapping size doesn't exceed 4G. */
1828339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (map_size < size) {
1838339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = EFBIG;
1848339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return NULL;
1858339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
1868339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
1878339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Map the section. */
1888339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef  WIN32
1898339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    /* Convert to Win32 page protection and mapping type. */
1908339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    win32_prot = PAGE_READONLY;
1918339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    win32_map = FILE_MAP_READ;
1928339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (prot != PROT_NONE) {
1938339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        if ((prot & (PROT_WRITE | PROT_EXEC)) == 0) {
1948339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_prot = PAGE_READONLY;
1958339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_map = FILE_MAP_READ;
1968339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        } else if ((prot & (PROT_WRITE | PROT_EXEC)) ==
1978339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine                   (PROT_WRITE | PROT_EXEC)) {
1988339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_prot = PAGE_EXECUTE_READWRITE;
1998339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_map = FILE_MAP_WRITE;
2008339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        } else if ((prot & PROT_WRITE) == PROT_WRITE) {
2018339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_prot = PAGE_READWRITE;
2028339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_map = FILE_MAP_WRITE;
2038339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        } else if ((prot & PROT_EXEC) == PROT_EXEC) {
2048339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_prot = PAGE_EXECUTE_READ;
2058339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine            win32_map = FILE_MAP_READ;
2068339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        }
2078339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
2088339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
2098339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    converter.QuadPart = map_offset + map_size;
2108339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    map_handle = CreateFileMapping(handle, NULL, win32_prot,
2118339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine                                   converter.HighPart, converter.LowPart, NULL);
2128339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (map_handle != NULL) {
2138339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        converter.QuadPart = map_offset;
2148339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        mapped_at = MapViewOfFile(map_handle, win32_map, converter.HighPart,
2158339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine                                  converter.LowPart, map_size);
2168339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        /* Memory mapping (if successful) will hold extra references to the
2178339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        * mapping, so we can close it right after we mapped file view. */
2188339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        CloseHandle(map_handle);
2198339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
2208339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (mapped_at == NULL) {
2218339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
2228339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return NULL;
2238339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
2248339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
2258339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    mapped_at =
2268339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        mmap(0, map_size, PROT_READ, MAP_SHARED, (int)handle, map_offset);
2278339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (mapped_at == MAP_FAILED) {
2288339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return NULL;
2298339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
2308339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
2318339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
2328339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    *mapped_offset = (char*)mapped_at + (offset - map_offset);
2338339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    *mapped_size = size;
2348339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
2358339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return mapped_at;
2368339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
2378339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine
2388339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkineint
2398339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkinemapfile_unmap(void* mapped_at, size_t len)
2408339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine{
2418339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#ifdef WIN32
2428339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    if (!UnmapViewOfFile(mapped_at)) {
2438339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        errno = GetLastError();
2448339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine        return -1;
2458339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    }
2468339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return 0;
2478339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#else   // WIN32
2488339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine    return munmap(mapped_at, len);
2498339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine#endif  // WIN32
2508339d18223eed408bfefcd00f649a2b13ccac52cVladimir Chtchetkine}
251