]> git.proxmox.com Git - libgit2.git/blame - src/win32/map.c
More improvements to callback return value tests
[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
RJ
7
8#include "map.h"
9#include <errno.h>
10
11
12static DWORD get_page_size(void)
13{
14 static DWORD page_size;
15 SYSTEM_INFO sys;
16
17 if (!page_size) {
18 GetSystemInfo(&sys);
19 page_size = sys.dwAllocationGranularity;
20 }
21
22 return page_size;
23}
24
f79026b4 25int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
79ca2edc
RJ
26{
27 HANDLE fh = (HANDLE)_get_osfhandle(fd);
28 DWORD page_size = get_page_size();
29 DWORD fmap_prot = 0;
30 DWORD view_prot = 0;
31 DWORD off_low = 0;
87d9869f 32 DWORD off_hi = 0;
f0bde7fa
AB
33 git_off_t page_start;
34 git_off_t page_offset;
79ca2edc 35
e3c47510 36 GIT_MMAP_VALIDATE(out, len, prot, flags);
79ca2edc
RJ
37
38 out->data = NULL;
39 out->len = 0;
40 out->fmh = NULL;
41
42 if (fh == INVALID_HANDLE_VALUE) {
43 errno = EBADF;
e1de726c
RB
44 giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
45 return -1;
79ca2edc
RJ
46 }
47
48 if (prot & GIT_PROT_WRITE)
49 fmap_prot |= PAGE_READWRITE;
50 else if (prot & GIT_PROT_READ)
51 fmap_prot |= PAGE_READONLY;
79ca2edc
RJ
52
53 if (prot & GIT_PROT_WRITE)
54 view_prot |= FILE_MAP_WRITE;
55 if (prot & GIT_PROT_READ)
56 view_prot |= FILE_MAP_READ;
57
79ca2edc
RJ
58 page_start = (offset / page_size) * page_size;
59 page_offset = offset - page_start;
60
87d9869f 61 if (page_offset != 0) { /* offset must be multiple of page size */
79ca2edc 62 errno = EINVAL;
e1de726c
RB
63 giterr_set(GITERR_OS, "Failed to mmap. Offset must be multiple of page size");
64 return -1;
79ca2edc
RJ
65 }
66
67 out->fmh = CreateFileMapping(fh, NULL, fmap_prot, 0, 0, NULL);
68 if (!out->fmh || out->fmh == INVALID_HANDLE_VALUE) {
e1de726c 69 giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
79ca2edc 70 out->fmh = NULL;
e1de726c 71 return -1;
79ca2edc
RJ
72 }
73
f0bde7fa 74 assert(sizeof(git_off_t) == 8);
e1de726c 75
79ca2edc 76 off_low = (DWORD)(page_start);
90d4d2f0 77 off_hi = (DWORD)(page_start >> 32);
79ca2edc
RJ
78 out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len);
79 if (!out->data) {
e1de726c 80 giterr_set(GITERR_OS, "Failed to mmap. No data written");
79ca2edc
RJ
81 CloseHandle(out->fmh);
82 out->fmh = NULL;
e1de726c 83 return -1;
79ca2edc
RJ
84 }
85 out->len = len;
86
e1de726c 87 return 0;
79ca2edc
RJ
88}
89
f79026b4 90int p_munmap(git_map *map)
79ca2edc 91{
e1de726c 92 int error = 0;
79ca2edc 93
e1de726c 94 assert(map != NULL);
79ca2edc
RJ
95
96 if (map->data) {
97 if (!UnmapViewOfFile(map->data)) {
e1de726c
RB
98 giterr_set(GITERR_OS, "Failed to munmap. Could not unmap view of file");
99 error = -1;
79ca2edc
RJ
100 }
101 map->data = NULL;
102 }
103
104 if (map->fmh) {
105 if (!CloseHandle(map->fmh)) {
e1de726c
RB
106 giterr_set(GITERR_OS, "Failed to munmap. Could not close handle");
107 error = -1;
79ca2edc
RJ
108 }
109 map->fmh = NULL;
110 }
111
e1de726c 112 return error;
79ca2edc
RJ
113}
114
115