197 lines
5.4 KiB
C++
197 lines
5.4 KiB
C++
/*
|
|
This file is part of the KDE libraries
|
|
Copyright (c) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
|
|
|
|
These sources are based on ftp://g.oswego.edu/pub/misc/malloc.c
|
|
file by Doug Lea, released to the public domain.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <winposix_export.h>
|
|
#include <windows.h>
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <io.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/socket.h>
|
|
|
|
#ifndef SECTION_MAP_EXECUTE_EXPLICIT
|
|
//not defined in the February 2003 version of the Platform SDK
|
|
#define SECTION_MAP_EXECUTE_EXPLICIT 0x0020
|
|
#endif
|
|
|
|
#ifndef FILE_MAP_EXECUTE
|
|
//not defined in the February 2003 version of the Platform SDK
|
|
#define FILE_MAP_EXECUTE SECTION_MAP_EXECUTE_EXPLICIT
|
|
#endif
|
|
|
|
#define MUNMAP_FAILURE (-1)
|
|
|
|
#define USE_MALLOC_LOCK 1
|
|
|
|
struct mmapInfos {
|
|
HANDLE hFile; // the duplicated fd
|
|
HANDLE hMap; // handle returned by CreateFileMapping
|
|
void* start; // ptr returned by MapViewOfFile
|
|
};
|
|
|
|
CRITICAL_SECTION cs;
|
|
|
|
// rmills - only change is to add long to the following 2 lines
|
|
static long g_curMMapInfos = 0;
|
|
static long g_maxMMapInfos = -1;
|
|
static struct mmapInfos *g_mmapInfos = NULL;
|
|
#define NEW_MMAP_STRUCT_CNT 10
|
|
|
|
static int mapProtFlags(int flags, DWORD *dwAccess)
|
|
{
|
|
if ( ( flags & PROT_READ ) == PROT_READ ) {
|
|
if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
|
|
*dwAccess = FILE_MAP_WRITE;
|
|
if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
|
|
return PAGE_EXECUTE_READWRITE;
|
|
}
|
|
return PAGE_READWRITE;
|
|
}
|
|
if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
|
|
*dwAccess = FILE_MAP_EXECUTE;
|
|
return PAGE_EXECUTE_READ;
|
|
}
|
|
*dwAccess = FILE_MAP_READ;
|
|
return PAGE_READONLY;
|
|
}
|
|
if ( ( flags & PROT_WRITE ) == PROT_WRITE ) {
|
|
*dwAccess = FILE_MAP_COPY;
|
|
return PAGE_WRITECOPY;
|
|
}
|
|
if ( ( flags & PROT_EXEC ) == PROT_EXEC ) {
|
|
*dwAccess = FILE_MAP_EXECUTE;
|
|
return PAGE_EXECUTE_READ;
|
|
}
|
|
*dwAccess = 0;
|
|
return 0;
|
|
}
|
|
|
|
void *mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
|
|
{
|
|
struct mmapInfos mmi;
|
|
DWORD dwAccess;
|
|
DWORD flProtect;
|
|
HANDLE hfd;
|
|
|
|
if ( g_maxMMapInfos == -1 ) {
|
|
g_maxMMapInfos = 0;
|
|
InitializeCriticalSection( &cs );
|
|
}
|
|
|
|
flProtect = mapProtFlags( flags, &dwAccess );
|
|
if ( flProtect == 0 ) {
|
|
_set_errno( EINVAL );
|
|
return MAP_FAILED;
|
|
}
|
|
// we don't support this atm
|
|
if ( prot == MAP_FIXED ) {
|
|
_set_errno( ENOTSUP );
|
|
return MAP_FAILED;
|
|
}
|
|
|
|
if ( fd == -1 ) {
|
|
_set_errno( EBADF );
|
|
return MAP_FAILED;
|
|
}
|
|
|
|
hfd = (HANDLE)_get_osfhandle( fd );
|
|
if ( hfd == INVALID_HANDLE_VALUE )
|
|
return MAP_FAILED;
|
|
|
|
if ( !DuplicateHandle( GetCurrentProcess(), hfd, GetCurrentProcess(),
|
|
&mmi.hFile, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
|
|
#ifdef _DEBUG
|
|
DWORD dwLastErr = GetLastError();
|
|
#endif
|
|
return MAP_FAILED;
|
|
}
|
|
mmi.hMap = CreateFileMapping( mmi.hFile, NULL, flProtect,
|
|
0, length, NULL );
|
|
if ( mmi.hMap == 0 ) {
|
|
_set_errno( EACCES );
|
|
return MAP_FAILED;
|
|
}
|
|
|
|
mmi.start = MapViewOfFile( mmi.hMap, dwAccess, 0, offset, 0 );
|
|
if ( mmi.start == 0 ) {
|
|
DWORD dwLastErr = GetLastError();
|
|
if ( dwLastErr == ERROR_MAPPED_ALIGNMENT )
|
|
_set_errno( EINVAL );
|
|
else
|
|
_set_errno( EACCES );
|
|
return MAP_FAILED;
|
|
}
|
|
EnterCriticalSection( &cs );
|
|
if ( g_mmapInfos == NULL ) {
|
|
g_maxMMapInfos = NEW_MMAP_STRUCT_CNT;
|
|
g_mmapInfos = ( struct mmapInfos* )calloc( g_maxMMapInfos,
|
|
sizeof( struct mmapInfos ) );
|
|
}
|
|
if( g_curMMapInfos == g_maxMMapInfos) {
|
|
g_maxMMapInfos += NEW_MMAP_STRUCT_CNT;
|
|
g_mmapInfos = ( struct mmapInfos* )realloc( g_mmapInfos,
|
|
g_maxMMapInfos * sizeof( struct mmapInfos ) );
|
|
}
|
|
memcpy( &g_mmapInfos[g_curMMapInfos], &mmi, sizeof( struct mmapInfos) );
|
|
g_curMMapInfos++;
|
|
|
|
LeaveCriticalSection( &cs );
|
|
|
|
return mmi.start;
|
|
}
|
|
|
|
int munmap(void *start, size_t length)
|
|
{
|
|
int i, j;
|
|
|
|
for( i = 0; i < g_curMMapInfos; i++ ) {
|
|
if( g_mmapInfos[i].start == start )
|
|
break;
|
|
}
|
|
if( i == g_curMMapInfos ) {
|
|
_set_errno( EINVAL );
|
|
return -1;
|
|
}
|
|
|
|
UnmapViewOfFile( g_mmapInfos[i].start );
|
|
CloseHandle( g_mmapInfos[i].hMap );
|
|
CloseHandle( g_mmapInfos[i].hFile );
|
|
|
|
EnterCriticalSection( &cs );
|
|
for( j = i + 1; j < g_curMMapInfos; j++ ) {
|
|
memcpy( &g_mmapInfos[ j - 1 ], &g_mmapInfos[ j ],
|
|
sizeof( struct mmapInfos ) );
|
|
}
|
|
g_curMMapInfos--;
|
|
|
|
if( g_curMMapInfos == 0 ) {
|
|
free( g_mmapInfos );
|
|
g_mmapInfos = NULL;
|
|
g_maxMMapInfos = 0;
|
|
}
|
|
LeaveCriticalSection( &cs );
|
|
|
|
return 0;
|
|
}
|