]> git.proxmox.com Git - libgit2.git/blame - src/win32/map.c
win32: Add routines to abstract memory-mapped file functions
[libgit2.git] / src / win32 / map.c
CommitLineData
79ca2edc
RJ
1
2#include "map.h"
3#include <errno.h>
4
5
6static DWORD get_page_size(void)
7{
8 static DWORD page_size;
9 SYSTEM_INFO sys;
10
11 if (!page_size) {
12 GetSystemInfo(&sys);
13 page_size = sys.dwAllocationGranularity;
14 }
15
16 return page_size;
17}
18
19int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offset)
20{
21 HANDLE fh = (HANDLE)_get_osfhandle(fd);
22 DWORD page_size = get_page_size();
23 DWORD fmap_prot = 0;
24 DWORD view_prot = 0;
25 DWORD off_low = 0;
26 DWORD off_hi = 0;
27 off_t page_start;
28 off_t page_offset;
29
30 assert((out != NULL) && (len > 0));
31
32 if ((out == NULL) || (len == 0)) {
33 errno = EINVAL;
34 return GIT_ERROR;
35 }
36
37 out->data = NULL;
38 out->len = 0;
39 out->fmh = NULL;
40
41 if (fh == INVALID_HANDLE_VALUE) {
42 errno = EBADF;
43 return GIT_ERROR;
44 }
45
46 if (prot & GIT_PROT_WRITE)
47 fmap_prot |= PAGE_READWRITE;
48 else if (prot & GIT_PROT_READ)
49 fmap_prot |= PAGE_READONLY;
50 else {
51 errno = EINVAL;
52 return GIT_ERROR;
53 }
54
55 if (prot & GIT_PROT_WRITE)
56 view_prot |= FILE_MAP_WRITE;
57 if (prot & GIT_PROT_READ)
58 view_prot |= FILE_MAP_READ;
59
60 if (flags & GIT_MAP_FIXED) {
61 errno = EINVAL;
62 return GIT_ERROR;
63 }
64
65 page_start = (offset / page_size) * page_size;
66 page_offset = offset - page_start;
67
68 if (page_offset != 0) { /* offset must be multiple of page size */
69 errno = EINVAL;
70 return GIT_ERROR;
71 }
72
73 out->fmh = CreateFileMapping(fh, NULL, fmap_prot, 0, 0, NULL);
74 if (!out->fmh || out->fmh == INVALID_HANDLE_VALUE) {
75 /* errno = ? */
76 out->fmh = NULL;
77 return GIT_ERROR;
78 }
79
80 off_low = (DWORD)(page_start);
81 if (sizeof(off_t) > 4)
82 off_hi = (DWORD)(page_start >> 32);
83 out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len);
84 if (!out->data) {
85 /* errno = ? */
86 CloseHandle(out->fmh);
87 out->fmh = NULL;
88 return GIT_ERROR;
89 }
90 out->len = len;
91
92 return GIT_SUCCESS;
93}
94
95int git__munmap(git_map *map)
96{
97 assert(map != NULL);
98
99 if (!map)
100 return GIT_ERROR;
101
102 if (map->data) {
103 if (!UnmapViewOfFile(map->data)) {
104 /* errno = ? */
105 CloseHandle(map->fmh);
106 map->data = NULL;
107 map->fmh = NULL;
108 return GIT_ERROR;
109 }
110 map->data = NULL;
111 }
112
113 if (map->fmh) {
114 if (!CloseHandle(map->fmh)) {
115 /* errno = ? */
116 map->fmh = NULL;
117 return GIT_ERROR;
118 }
119 map->fmh = NULL;
120 }
121
122 return GIT_SUCCESS;
123}
124
125