the key argument is const, mark it as such
[heimdal.git] / lib / roken / test-mem.c
blobd270d8f806c8d4fc5c0b2510b619db27784fd6c8
1 /*
2 * Copyright (c) 1999 - 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <config.h>
36 #ifdef HAVE_SYS_MMAN_H
37 #include <sys/mman.h>
38 #endif
39 #include <stdio.h>
40 #include <string.h>
41 #include <err.h>
42 #include "roken.h"
44 #include "test-mem.h"
46 RCSID("$Id$");
48 /* #undef HAVE_MMAP */
50 struct {
51 void *start;
52 size_t size;
53 void *data_start;
54 size_t data_size;
55 enum rk_test_mem_type type;
56 int fd;
57 } map;
59 struct sigaction sa, osa;
61 char *testname;
63 static RETSIGTYPE
64 segv_handler(int sig)
66 int fd;
67 char msg[] = "SIGSEGV i current test: ";
69 fd = open("/dev/stdout", O_WRONLY, 0600);
70 if (fd >= 0) {
71 write(fd, msg, sizeof(msg) - 1);
72 write(fd, testname, strlen(testname));
73 write(fd, "\n", 1);
74 close(fd);
76 _exit(1);
79 #define TESTREC() \
80 if (testname) \
81 errx(1, "test %s run recursively on %s", name, testname); \
82 testname = strdup(name); \
83 if (testname == NULL) \
84 errx(1, "malloc");
87 void * ROKEN_LIB_FUNCTION
88 rk_test_mem_alloc(enum rk_test_mem_type type, const char *name,
89 void *buf, size_t size)
91 #ifndef HAVE_MMAP
92 unsigned char *p;
94 TESTREC();
96 p = malloc(size + 2);
97 if (p == NULL)
98 errx(1, "malloc");
99 map.type = type;
100 map.start = p;
101 map.size = size + 2;
102 p[0] = 0xff;
103 p[map.size] = 0xff;
104 map.data_start = p + 1;
105 #else
106 unsigned char *p;
107 int flags, ret, fd;
108 size_t pagesize = getpagesize();
110 TESTREC();
112 map.type = type;
114 #ifdef MAP_ANON
115 flags = MAP_ANON;
116 fd = -1;
117 #else
118 flags = 0;
119 fd = open ("/dev/zero", O_RDONLY);
120 if(fd < 0)
121 err (1, "open /dev/zero");
122 #endif
123 map.fd = fd;
124 flags |= MAP_PRIVATE;
126 map.size = size + pagesize - (size % pagesize) + pagesize * 2;
128 p = (unsigned char *)mmap(0, map.size, PROT_READ | PROT_WRITE,
129 flags, fd, 0);
130 if (p == (unsigned char *)MAP_FAILED)
131 err (1, "mmap");
133 map.start = p;
135 ret = mprotect ((void *)p, pagesize, 0);
136 if (ret < 0)
137 err (1, "mprotect");
139 ret = mprotect (p + map.size - pagesize, pagesize, 0);
140 if (ret < 0)
141 err (1, "mprotect");
143 switch (type) {
144 case RK_TM_OVERRUN:
145 map.data_start = p + map.size - pagesize - size;
146 break;
147 case RK_TM_UNDERRUN:
148 map.data_start = p + pagesize;
149 break;
150 default:
151 abort();
153 #endif
154 sigemptyset (&sa.sa_mask);
155 sa.sa_flags = 0;
156 #ifdef SA_RESETHAND
157 sa.sa_flags |= SA_RESETHAND;
158 #endif
159 sa.sa_handler = segv_handler;
160 sigaction (SIGSEGV, &sa, &osa);
162 map.data_size = size;
163 if (buf)
164 memcpy(map.data_start, buf, size);
165 return map.data_start;
168 void ROKEN_LIB_FUNCTION
169 rk_test_mem_free(const char *map_name)
171 #ifndef HAVE_MMAP
172 unsigned char *p = map.start;
174 if (testname == NULL)
175 errx(1, "test_mem_free call on no free");
177 if (p[0] != 0xff)
178 errx(1, "%s: %s underrun %x\n", testname, map_name, p[0]);
179 if (p[map.size] != 0xff)
180 errx(1, "%s: %s overrun %x\n", testname, map_name, p[map.size - 1]);
181 free(map.start);
182 #else
183 int ret;
185 if (testname == NULL)
186 errx(1, "test_mem_free call on no free");
188 ret = munmap (map.start, map.size);
189 if (ret < 0)
190 err (1, "munmap");
191 if (map.fd > 0)
192 close(map.fd);
193 #endif
194 free(testname);
195 testname = NULL;
197 sigaction (SIGSEGV, &osa, NULL);