From effb6040ee1852fcea1fcd7a12493cef01c3e092 Mon Sep 17 00:00:00 2001 From: diego Date: Wed, 27 Feb 2008 22:29:52 +0000 Subject: mmap() support for OS/2 patch by KO Myung-Hun, komh chollian net git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@26108 b3059339-0415-0410-9bf9-f77b7e298cf2 --- osdep/Makefile | 3 + osdep/mmap-os2.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ osdep/mmap.h | 56 +++++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 osdep/mmap-os2.c create mode 100644 osdep/mmap.h (limited to 'osdep') diff --git a/osdep/Makefile b/osdep/Makefile index 43f3e08d59..c0f7a2c7ec 100644 --- a/osdep/Makefile +++ b/osdep/Makefile @@ -26,6 +26,9 @@ getch = getch2-win.c endif ifeq ($(TARGET_OS),OS/2) getch = getch2-os2.c +ifneq ($(HAVE_SYS_MMAN_H),yes) +SRCS_COMMON += mmap-os2.c +endif endif SRCS_COMMON += $(timer) SRCS_COMMON += $(getch) diff --git a/osdep/mmap-os2.c b/osdep/mmap-os2.c new file mode 100644 index 0000000000..7646296cd9 --- /dev/null +++ b/osdep/mmap-os2.c @@ -0,0 +1,210 @@ +/* + * very simple implementation of mmap() for OS/2 + * + * Copyright (c) 2008 KO Myung-Hun (komh@chollian.net) + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define INCL_DOS +#include + +#include +#include +#include +#include + +#include "config.h" +#include "mmap.h" +#include "mmap_anon.h" + +typedef struct os2_mmap_s +{ + void *addr; + size_t len; + int flags; + struct os2_mmap_s *prev; + struct os2_mmap_s *next; +} os2_mmap; +static os2_mmap *m_mmap = NULL; + +void *mmap( void *addr, size_t len, int prot, int flags, int fildes, off_t off ) +{ + os2_mmap *new_mmap; + + ULONG fl; + ULONG rc; + + void *ret; + + if( prot & PROT_WRITE ) + { + if( flags & MAP_SHARED ) + return MAP_FAILED; + + if( !( flags & MAP_PRIVATE )) + return MAP_FAILED; + } + + if( flags & MAP_FIXED ) + { + ULONG cb; + + cb = len; + rc = DosQueryMem( addr, &cb, &fl ); + if( rc || ( cb < len )) + return MAP_FAILED; + + rc = DosSetMem( addr, len, fPERM ); + if( rc ) + return MAP_FAILED; + + ret = addr; + } + else + { + // Allocate tiled memory compatible with 16-bit selectors + // 'fs_seg' in 'ldt_keeper.c' need this attribute + rc = DosAllocMem( &ret, len, fALLOC ); + if( rc ) + return MAP_FAILED; + } + + new_mmap = ( os2_mmap * )malloc( sizeof( os2_mmap )); + new_mmap->addr = ret; + new_mmap->len = len; + new_mmap->flags = flags; + new_mmap->prev = m_mmap; + new_mmap->next = NULL; + + if( m_mmap ) + m_mmap->next = new_mmap; + m_mmap = new_mmap; + + if( !( flags & MAP_ANON )) + { + int pos; + + /* Now read in the file */ + if(( pos = lseek( fildes, off, SEEK_SET )) == -1) + { + munmap( ret, len ); + + return MAP_FAILED; + } + + read( fildes, ret, len ); + lseek( fildes, pos, SEEK_SET ); /* Restore the file pointer */ + } + + fl = 0; + + if( prot & PROT_READ ) + fl |= PAG_READ; + + if( prot & PROT_WRITE ) + fl |= PAG_WRITE; + + if( prot & PROT_EXEC ) + fl |= PAG_EXECUTE; + + if( prot & PROT_NONE ) + fl |= PAG_GUARD; + + rc = DosSetMem( ret, len, fl ); + if( rc ) + { + munmap( ret, len ); + + return MAP_FAILED; + } + + return ret; +} + +int munmap( void *addr, size_t len ) +{ + os2_mmap *mm; + + for( mm = m_mmap; mm; mm = mm->prev ) + { + if( mm->addr == addr ) + break; + } + + if( mm ) + { + + if( !( mm->flags & MAP_FIXED )) + DosFreeMem( addr ); + + if( mm->next ) + mm->next->prev = mm->prev; + + if( mm->prev ) + mm->prev->next = mm->next; + + if( m_mmap == mm ) + m_mmap = mm->prev; + + free( mm ); + + return 0; + } + + return -1; +} + +int mprotect( void *addr, size_t len, int prot ) +{ + os2_mmap *mm; + + for( mm = m_mmap; mm; mm = mm->prev ) + { + if( mm->addr == addr ) + break; + } + + if( mm ) + { + ULONG fl; + + fl = 0; + + if( prot & PROT_READ ) + fl |= PAG_READ; + + if( prot & PROT_WRITE ) + fl |= PAG_WRITE; + + if( prot & PROT_EXEC ) + fl |= PAG_EXECUTE; + + if( prot & PROT_NONE ) + fl |= PAG_GUARD; + + if( DosSetMem( addr, len, fl ) == 0 ) + return 0; + } + + return -1; +} + +void *mmap_anon( void *addr, size_t len, int prot, int flags, off_t off ) +{ + return mmap( addr, len, prot, flags | MAP_ANON, -1, off ); +} diff --git a/osdep/mmap.h b/osdep/mmap.h new file mode 100644 index 0000000000..8a4ccc0abf --- /dev/null +++ b/osdep/mmap.h @@ -0,0 +1,56 @@ +/* + * mmap declaration header for systems with missing/nonfunctional sys/mman.h + * + * Copyright (c) 2008 KO Myung-Hun (komh@chollian.net) + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_MMAP_H +#define MPLAYER_MMAP_H + +/* + * Protections are chosen from these bits, or-ed together + */ +#define PROT_NONE 0x00 /* no permissions */ +#define PROT_READ 0x01 /* pages can be read */ +#define PROT_WRITE 0x02 /* pages can be written */ +#define PROT_EXEC 0x04 /* pages can be executed */ + +/* + * Flags contain sharing type and options. + * Sharing types; choose one. + */ +#define MAP_SHARED 0x0001 /* share changes */ +#define MAP_PRIVATE 0x0002 /* changes are private */ +#define MAP_FIXED 0x0010 /* map addr must be exactly as requested */ + +/* + * Mapping type + */ +#define MAP_ANON 0x1000 /* allocated from memory, swap space */ + +/* MAP_FAILED is defined in config.h */ + +#ifndef _MMAP_DECLARED +#define _MMAP_DECLARED +void *mmap( void *addr, size_t len, int prot, int flags, int fildes, off_t off ); +#endif +int munmap( void *addr, size_t len ); +int mprotect( void *addr, size_t len, int prot ); + +#endif /* MPLAYER_MMAP_H */ -- cgit v1.2.3