]> git.proxmox.com Git - libgit2.git/blame - src/win32/map.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / src / win32 / map.c
CommitLineData
bb742ede 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
bb742ede
VM
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
79ca2edc 7
eae0bfdc
PP
8#include "common.h"
9
79ca2edc
RJ
10#include "map.h"
11#include <errno.h>
12
7697e541 13#ifndef NO_MMAP
79ca2edc
RJ
14
15static DWORD get_page_size(void)
16{
17 static DWORD page_size;
18 SYSTEM_INFO sys;
19
20 if (!page_size) {
21 GetSystemInfo(&sys);
87c18197 22 page_size = sys.dwPageSize;
79ca2edc
RJ
23 }
24
25 return page_size;
26}
27
87c18197
CMN
28static DWORD get_allocation_granularity(void)
29{
30 static DWORD granularity;
31 SYSTEM_INFO sys;
32
33 if (!granularity) {
34 GetSystemInfo(&sys);
35 granularity = sys.dwAllocationGranularity;
36 }
37
38 return granularity;
39}
40
62e562f9 41int git__page_size(size_t *page_size)
f7310540 42{
62e562f9
AM
43 *page_size = get_page_size();
44 return 0;
f7310540
CMN
45}
46
87c18197
CMN
47int git__mmap_alignment(size_t *page_size)
48{
49 *page_size = get_allocation_granularity();
50 return 0;
51}
52
22a2d3d5 53int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset)
79ca2edc
RJ
54{
55 HANDLE fh = (HANDLE)_get_osfhandle(fd);
87c18197 56 DWORD alignment = get_allocation_granularity();
79ca2edc
RJ
57 DWORD fmap_prot = 0;
58 DWORD view_prot = 0;
59 DWORD off_low = 0;
87d9869f 60 DWORD off_hi = 0;
22a2d3d5
UG
61 off64_t page_start;
62 off64_t page_offset;
79ca2edc 63
e3c47510 64 GIT_MMAP_VALIDATE(out, len, prot, flags);
79ca2edc
RJ
65
66 out->data = NULL;
67 out->len = 0;
68 out->fmh = NULL;
69
70 if (fh == INVALID_HANDLE_VALUE) {
71 errno = EBADF;
ac3d33df 72 git_error_set(GIT_ERROR_OS, "failed to mmap. Invalid handle value");
e1de726c 73 return -1;
79ca2edc
RJ
74 }
75
76 if (prot & GIT_PROT_WRITE)
77 fmap_prot |= PAGE_READWRITE;
78 else if (prot & GIT_PROT_READ)
79 fmap_prot |= PAGE_READONLY;
79ca2edc
RJ
80
81 if (prot & GIT_PROT_WRITE)
82 view_prot |= FILE_MAP_WRITE;
83 if (prot & GIT_PROT_READ)
84 view_prot |= FILE_MAP_READ;
85
87c18197 86 page_start = (offset / alignment) * alignment;
79ca2edc
RJ
87 page_offset = offset - page_start;
88
87c18197 89 if (page_offset != 0) { /* offset must be multiple of the allocation granularity */
79ca2edc 90 errno = EINVAL;
ac3d33df 91 git_error_set(GIT_ERROR_OS, "failed to mmap. Offset must be multiple of allocation granularity");
e1de726c 92 return -1;
79ca2edc
RJ
93 }
94
95 out->fmh = CreateFileMapping(fh, NULL, fmap_prot, 0, 0, NULL);
96 if (!out->fmh || out->fmh == INVALID_HANDLE_VALUE) {
ac3d33df 97 git_error_set(GIT_ERROR_OS, "failed to mmap. Invalid handle value");
79ca2edc 98 out->fmh = NULL;
e1de726c 99 return -1;
79ca2edc
RJ
100 }
101
102 off_low = (DWORD)(page_start);
90d4d2f0 103 off_hi = (DWORD)(page_start >> 32);
79ca2edc
RJ
104 out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len);
105 if (!out->data) {
ac3d33df 106 git_error_set(GIT_ERROR_OS, "failed to mmap. No data written");
79ca2edc
RJ
107 CloseHandle(out->fmh);
108 out->fmh = NULL;
e1de726c 109 return -1;
79ca2edc
RJ
110 }
111 out->len = len;
112
e1de726c 113 return 0;
79ca2edc
RJ
114}
115
f79026b4 116int p_munmap(git_map *map)
79ca2edc 117{
e1de726c 118 int error = 0;
79ca2edc 119
c25aa7cd 120 GIT_ASSERT_ARG(map);
79ca2edc
RJ
121
122 if (map->data) {
123 if (!UnmapViewOfFile(map->data)) {
ac3d33df 124 git_error_set(GIT_ERROR_OS, "failed to munmap. Could not unmap view of file");
e1de726c 125 error = -1;
79ca2edc
RJ
126 }
127 map->data = NULL;
128 }
129
130 if (map->fmh) {
131 if (!CloseHandle(map->fmh)) {
ac3d33df 132 git_error_set(GIT_ERROR_OS, "failed to munmap. Could not close handle");
e1de726c 133 error = -1;
79ca2edc
RJ
134 }
135 map->fmh = NULL;
136 }
137
e1de726c 138 return error;
79ca2edc
RJ
139}
140
7697e541 141#endif