repository_infos: Enable automatic updates on the main Haiku repostiory.
[haiku.git] / src / tests / system / libroot / posix / mprotect_test.cpp
blobb79123a5e34712826c830b4603146056ef2235d7
1 /*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <errno.h>
7 #include <limits.h>
8 #include <signal.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 #include <string.h>
14 #include <sys/mman.h>
17 #ifndef PAGE_SIZE
18 # define PAGE_SIZE 4096
19 #endif
22 static const size_t kMapChunkSize = 4 * PAGE_SIZE;
23 static const size_t kTestSize = 256 * PAGE_SIZE;
25 static int64_t sHandledSignals = 0;
27 static uint8_t* sMappedBase;
28 static size_t sMappedSize;
29 static uint8_t* sTouchedAddress;
32 static void
33 signal_handler(int signal)
35 sHandledSignals++;
37 //printf("SIGSEGV at %p\n", sTouchedAddress);
39 // protect the last page of the current allocation writable
40 if (mprotect(sMappedBase + sMappedSize - PAGE_SIZE, PAGE_SIZE,
41 PROT_READ | PROT_WRITE) < 0) {
42 fprintf(stderr, "SIGSEGV: mprotect() failed: %s\n", strerror(errno));
43 exit(1);
46 // allocate the next chunk
47 void* mappedAddress = mmap(sMappedBase + sMappedSize, kMapChunkSize,
48 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
49 if (mappedAddress == MAP_FAILED) {
50 fprintf(stderr, "SIGSEGV: mmap() failed: %s\n", strerror(errno));
51 exit(1);
54 printf("mapped %d bytes at %p\n", (int)kMapChunkSize, mappedAddress);
56 sMappedSize += kMapChunkSize;
58 // map the last page read-only
59 if (mprotect(sMappedBase + sMappedSize - PAGE_SIZE, PAGE_SIZE, PROT_READ)
60 < 0) {
61 fprintf(stderr, "SIGSEGV: mprotect() failed: %s\n", strerror(errno));
62 exit(1);
67 int
68 main()
70 // install signal handler
71 if (signal(SIGSEGV, signal_handler) == SIG_ERR) {
72 fprintf(stderr, "Error: Failed to install signal handler: %s\n",
73 strerror(errno));
74 exit(1);
77 // Map the complete test size plus one chunk and unmap all but the first
78 // chunk again, so no other memory gets into the way, when we mmap() the
79 // other chunks with MAP_FIXED.
80 sMappedBase = (uint8_t*)mmap(NULL, kTestSize + kMapChunkSize,
81 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
82 if (sMappedBase == MAP_FAILED) {
83 fprintf(stderr, "mmap() failed: %s\n", strerror(errno));
84 return 1;
86 munmap(sMappedBase + kMapChunkSize, kTestSize);
88 sMappedSize = kMapChunkSize;
90 printf("mapped %d bytes at %p\n", (int)sMappedSize, sMappedBase);
92 if (mprotect(sMappedBase + sMappedSize - PAGE_SIZE, PAGE_SIZE, PROT_READ)
93 < 0) {
94 fprintf(stderr, "mprotect() failed: %s\n", strerror(errno));
95 return 1;
98 for (int i = 0; i < 256 * PAGE_SIZE; i++) {
99 sTouchedAddress = sMappedBase + i;
100 *sTouchedAddress = 1;
103 printf("test finished successfully!\n");
105 return 0;