xref: /haiku/src/system/libroot/posix/sys/mman.cpp (revision fc1ca2da5cfcb00ffdf791606d5ae97fdd58a638)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <sys/mman.h>
7 
8 #include <errno.h>
9 
10 #include <OS.h>
11 
12 #include <syscall_utils.h>
13 #include <syscalls.h>
14 #include <vm.h>
15 
16 
17 void*
18 mmap(void* address, size_t length, int protection, int flags, int fd,
19 	off_t offset)
20 {
21 	// offset and length must be page-aligned
22 	if (length == 0 || offset % B_PAGE_SIZE != 0) {
23 		errno = B_BAD_VALUE;
24 		return MAP_FAILED;
25 	}
26 
27 	// check anonymous mapping
28 	if ((flags & MAP_ANONYMOUS) != 0) {
29 		fd = -1;
30 	} else if (fd < 0) {
31 		errno = EBADF;
32 		return MAP_FAILED;
33 	}
34 
35 	// either MAP_SHARED or MAP_PRIVATE must be specified
36 	if (((flags & MAP_SHARED) != 0) == ((flags & MAP_PRIVATE) != 0)) {
37 		errno = B_BAD_VALUE;
38 		return MAP_FAILED;
39 	}
40 
41 	// translate mapping, address specification, and protection
42 	int mapping = (flags & MAP_SHARED) != 0
43 		? REGION_NO_PRIVATE_MAP : REGION_PRIVATE_MAP;
44 
45 	uint32 addressSpec = B_ANY_ADDRESS;
46 	if ((flags & MAP_FIXED) != 0)
47 		addressSpec = B_EXACT_ADDRESS;
48 
49 	uint32 areaProtection = 0;
50 	if ((protection & PROT_READ) != 0)
51 		areaProtection |= B_READ_AREA;
52 	if ((protection & PROT_WRITE) != 0)
53 		areaProtection |= B_WRITE_AREA;
54 	if ((protection & PROT_EXEC) != 0)
55 		areaProtection |= B_EXECUTE_AREA;
56 
57 	// ask the kernel to map
58 	area_id area = _kern_map_file("mmap area", &address, addressSpec,
59 		length, areaProtection, mapping, fd, offset);
60 	if (area < 0) {
61 		errno = area;
62 		return MAP_FAILED;
63 	}
64 
65 	return address;
66 }
67 
68 
69 int
70 munmap(void* address, size_t length)
71 {
72 	RETURN_AND_SET_ERRNO(_kern_unmap_memory(address, length));
73 }
74