Main Page | File List | Globals

src/mmap.c

Go to the documentation of this file.
00001 /*
00002      This file is part of PlibC.
00003      (C) 2005 Nils Durner (and other contributing authors)
00004 
00005            This library is free software; you can redistribute it and/or
00006            modify it under the terms of the GNU Lesser General Public
00007            License as published by the Free Software Foundation; either
00008            version 2.1 of the License, or (at your option) any later version.
00009         
00010            This library is distributed in the hope that it will be useful,
00011            but WITHOUT ANY WARRANTY; without even the implied warranty of
00012            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013            Lesser General Public License for more details.
00014         
00015            You should have received a copy of the GNU Lesser General Public
00016            License along with this library; if not, write to the Free Software
00017            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00025 #include "plibc_private.h"
00026 
00027 extern unsigned int uiMappingsCount;
00028 extern TMapping *pMappings;
00029 extern HANDLE hMappingsLock;
00030 
00036 void *_win_mmap(void *start, size_t len, int access, int flags, int fd,
00037                 unsigned long long off) {
00038   DWORD protect, high, low, access_param;
00039   HANDLE h, hFile;
00040   SECURITY_ATTRIBUTES sec_none;
00041   void *base;
00042   BOOL bFound = FALSE;
00043   unsigned int uiIndex;
00044 
00045   errno = 0;
00046 
00047   switch(access)
00048   {
00049     case PROT_WRITE:
00050       protect = PAGE_READWRITE;
00051       access_param = FILE_MAP_WRITE;
00052       break;
00053     case PROT_READ:
00054       protect = PAGE_READONLY;
00055       access_param = FILE_MAP_READ;
00056       break;
00057     default:
00058       protect = PAGE_WRITECOPY;
00059       access_param = FILE_MAP_COPY;
00060       break;
00061   }
00062 
00063   sec_none.nLength = sizeof(SECURITY_ATTRIBUTES);
00064   sec_none.bInheritHandle = TRUE;
00065   sec_none.lpSecurityDescriptor = NULL;
00066 
00067   hFile = (HANDLE) _get_osfhandle(fd);
00068 
00069   h = CreateFileMapping(hFile, &sec_none, protect, 0, 0, NULL);
00070 
00071   if (! h)
00072   {
00073     SetErrnoFromWinError(GetLastError());
00074     return (void *) -1;
00075   }
00076 
00077   high = off >> 32;
00078   low = off & ULONG_MAX;
00079   base = NULL;
00080 
00081   /* If a non-zero start is given, try mapping using the given address first.
00082      If it fails and flags is not MAP_FIXED, try again with NULL address. */
00083   if (start)
00084     base = MapViewOfFileEx(h, access_param, high, low, len, start);
00085   if (!base && !(flags & MAP_FIXED))
00086     base = MapViewOfFileEx(h, access_param, high, low, len, NULL);
00087 
00088   if (!base || ((flags & MAP_FIXED) && base != start))
00089   {
00090     if (!base)
00091       SetErrnoFromWinError(GetLastError());
00092     else
00093       errno = EINVAL;
00094 
00095     CloseHandle(h);
00096     return (void *) -1;
00097   }
00098 
00099   /* Save mapping handle */
00100   WaitForSingleObject(hMappingsLock, INFINITE);
00101 
00102   for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++)
00103   {
00104     if (pMappings[uiIndex].pStart == base)
00105     {
00106       bFound = 1;
00107       break;
00108     }
00109   }
00110 
00111   if (! bFound)
00112   {
00113     uiIndex = 0;
00114 
00115     while(TRUE)
00116     {
00117       if (pMappings[uiIndex].pStart == NULL)
00118       {
00119         pMappings[uiIndex].pStart = base;
00120         pMappings[uiIndex].hMapping = h;
00121       }
00122       if (uiIndex == uiMappingsCount)
00123       {
00124         uiMappingsCount++;
00125         pMappings = (TMapping *) realloc(pMappings, (uiMappingsCount + 1) * sizeof(TMapping));
00126         pMappings[uiMappingsCount].pStart = NULL;
00127 
00128         break;
00129       }
00130       uiIndex++;
00131     }
00132   }
00133   ReleaseMutex(hMappingsLock);
00134 
00135   return base;
00136 }
00137 
00143 int _win_munmap(void *start, size_t length)
00144 {
00145   unsigned uiIndex;
00146   BOOL success = UnmapViewOfFile(start);
00147   SetErrnoFromWinError(GetLastError());
00148 
00149   if (success)
00150   {
00151     /* Release mapping handle */
00152     WaitForSingleObject(hMappingsLock, INFINITE);
00153 
00154     for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++)
00155     {
00156       if (pMappings[uiIndex].pStart == start)
00157       {
00158         success = CloseHandle(pMappings[uiIndex].hMapping);
00159         SetErrnoFromWinError(GetLastError());
00160         pMappings[uiIndex].pStart = NULL;
00161         pMappings[uiIndex].hMapping = NULL;
00162 
00163         break;
00164       }
00165     }
00166 
00167     ReleaseMutex(hMappingsLock);
00168   }
00169 
00170   return success ? 0 : -1;
00171 }
00172 
00173 /* end of mmap.c */

Generated on Sun Sep 4 11:16:47 2005 for PlibC by  doxygen 1.4.2