Spaces:
Running
Running
| static int __map_mman_error(const uint32_t err, const int deferr) | |
| { | |
| if (err == 0) | |
| return 0; | |
| //TODO: implement | |
| return err; | |
| } | |
| static uint32_t __map_mmap_prot_page(const int prot) | |
| { | |
| uint32_t protect = 0; | |
| if (prot == PROT_NONE) | |
| return protect; | |
| if ((prot & PROT_EXEC) != 0) | |
| { | |
| protect = ((prot & PROT_WRITE) != 0) ? | |
| PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; | |
| } | |
| else | |
| { | |
| protect = ((prot & PROT_WRITE) != 0) ? | |
| PAGE_READWRITE : PAGE_READONLY; | |
| } | |
| return protect; | |
| } | |
| static uint32_t __map_mmap_prot_file(const int prot) | |
| { | |
| uint32_t desiredAccess = 0; | |
| if (prot == PROT_NONE) | |
| return desiredAccess; | |
| if ((prot & PROT_READ) != 0) | |
| desiredAccess |= FILE_MAP_READ; | |
| if ((prot & PROT_WRITE) != 0) | |
| desiredAccess |= FILE_MAP_WRITE; | |
| if ((prot & PROT_EXEC) != 0) | |
| desiredAccess |= FILE_MAP_EXECUTE; | |
| return desiredAccess; | |
| } | |
| void* mmap(void *addr, size_t len, int prot, int flags, int fildes, ssize_t off) | |
| { | |
| HANDLE fm, h; | |
| void * map = MAP_FAILED; | |
| const uint32_t dwFileOffsetLow = (uint32_t)(off & 0xFFFFFFFFL); | |
| const uint32_t dwFileOffsetHigh = (uint32_t)((off >> 32) & 0xFFFFFFFFL); | |
| const uint32_t protect = __map_mmap_prot_page(prot); | |
| const uint32_t desiredAccess = __map_mmap_prot_file(prot); | |
| const ssize_t maxSize = off + (ssize_t)len; | |
| const uint32_t dwMaxSizeLow = (uint32_t)(maxSize & 0xFFFFFFFFL); | |
| const uint32_t dwMaxSizeHigh = (uint32_t)((maxSize >> 32) & 0xFFFFFFFFL); | |
| errno = 0; | |
| if (len == 0 | |
| /* Unsupported flag combinations */ | |
| || (flags & MAP_FIXED) != 0 | |
| /* Usupported protection combinations */ | |
| || prot == PROT_EXEC) | |
| { | |
| errno = EINVAL; | |
| return MAP_FAILED; | |
| } | |
| h = ((flags & MAP_ANONYMOUS) == 0) ? | |
| (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; | |
| if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) | |
| { | |
| errno = EBADF; | |
| return MAP_FAILED; | |
| } | |
| fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); | |
| if (fm == NULL) | |
| { | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return MAP_FAILED; | |
| } | |
| map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); | |
| CloseHandle(fm); | |
| if (map == NULL) | |
| { | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return MAP_FAILED; | |
| } | |
| return map; | |
| } | |
| int munmap(void *addr, size_t len) | |
| { | |
| if (UnmapViewOfFile(addr)) | |
| return 0; | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return -1; | |
| } | |
| int mprotect(void *addr, size_t len, int prot) | |
| { | |
| uint32_t newProtect = __map_mmap_prot_page(prot); | |
| uint32_t oldProtect = 0; | |
| if (VirtualProtect(addr, len, newProtect, &oldProtect)) | |
| return 0; | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return -1; | |
| } | |
| int msync(void *addr, size_t len, int flags) | |
| { | |
| if (FlushViewOfFile(addr, len)) | |
| return 0; | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return -1; | |
| } | |
| int mlock(const void *addr, size_t len) | |
| { | |
| if (VirtualLock((LPVOID)addr, len)) | |
| return 0; | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return -1; | |
| } | |
| int munlock(const void *addr, size_t len) | |
| { | |
| if (VirtualUnlock((LPVOID)addr, len)) | |
| return 0; | |
| errno = __map_mman_error(GetLastError(), EPERM); | |
| return -1; | |
| } | |
| // Portable clock_gettime function for Windows | |
| int clock_gettime(int clk_id, struct timespec *tp) { | |
| uint32_t ticks = GetTickCount(); | |
| tp->tv_sec = ticks / 1000; | |
| tp->tv_nsec = (ticks % 1000) * 1000000; | |
| return 0; | |
| } | |