Sync usage with man page.
[netbsd-mini2440.git] / dist / ntp / ElectricFence / eftest.c
blob7717aceb0f947427c5c8c4a5ecbf74a5da1a299b
1 /* $NetBSD$ */
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <setjmp.h>
8 #include <signal.h>
9 #include "efence.h"
12 * Electric Fence confidence tests.
13 * Make sure all of the various functions of Electric Fence work correctly.
16 #ifndef PAGE_PROTECTION_VIOLATED_SIGNAL
17 #define PAGE_PROTECTION_VIOLATED_SIGNAL SIGSEGV
18 #endif
20 struct diagnostic {
21 int (*test)(void);
22 int expectedStatus;
23 const char * explanation;
26 extern int EF_PROTECT_BELOW;
27 extern int EF_ALIGNMENT;
29 static jmp_buf env;
32 * There is still too little standardization of the arguments and return
33 * type of signal handler functions.
35 static
36 void
37 segmentationFaultHandler(
38 int signalNumber
39 #if ( defined(_AIX) )
40 , ...
41 #endif
44 signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
45 longjmp(env, 1);
48 static int
49 gotSegmentationFault(int (*test)(void))
51 if ( setjmp(env) == 0 ) {
52 int status;
54 signal(PAGE_PROTECTION_VIOLATED_SIGNAL
55 ,segmentationFaultHandler);
56 status = (*test)();
57 signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
58 return status;
60 else
61 return 1;
64 static char * allocation;
65 /* c is global so that assignments to it won't be optimized out. */
66 char c;
68 static int
69 testSizes(void)
72 * If ef_number can't hold all of the bits of a void *, have the user
73 * add -DUSE_ LONG_LONG to the compiler flags so that ef_number will be
74 * declared as "unsigned long long" instead of "unsigned long".
76 return ( sizeof(ef_number) < sizeof(void *) );
79 static int
80 allocateMemory(void)
82 allocation = (char *)malloc(1);
84 if ( allocation != 0 )
85 return 0;
86 else
87 return 1;
90 static int
91 freeMemory(void)
93 free(allocation);
94 return 0;
97 static int
98 protectBelow(void)
100 EF_PROTECT_BELOW = 1;
101 return 0;
104 static int
105 read0(void)
107 c = *allocation;
109 return 0;
112 static int
113 write0(void)
115 *allocation = 1;
117 return 0;
120 static int
121 read1(void)
123 c = allocation[1];
125 return 0;
128 static int
129 readMinus1(void)
131 c = allocation[-1];
132 return 0;
135 static struct diagnostic diagnostics[] = {
137 testSizes, 0,
138 "Please add -DLONG_LONG to the compiler flags and recompile."
141 allocateMemory, 0,
142 "Allocation 1: This test allocates a single byte of memory."
145 read0, 0,
146 "Read valid memory 1: This test reads the allocated memory."
149 write0, 0,
150 "Write valid memory 1: This test writes the allocated memory."
153 read1, 1,
154 "Read overrun: This test reads beyond the end of the buffer."
157 freeMemory, 0,
158 "Free memory: This test frees the allocated memory."
161 protectBelow, 0,
162 "Protect below: This sets Electric Fence to protect\n"
163 "the lower boundary of a malloc buffer, rather than the\n"
164 "upper boundary."
167 allocateMemory, 0,
168 "Allocation 2: This allocates memory with the lower boundary"
169 " protected."
172 read0, 0,
173 "Read valid memory 2: This test reads the allocated memory."
176 write0, 0,
177 "Write valid memory 2: This test writes the allocated memory."
180 readMinus1, 1,
181 "Read underrun: This test reads before the beginning of the"
182 " buffer."
185 0, 0, 0
189 static const char failedTest[]
190 = "Electric Fence confidence test failed.\n";
192 static const char newline = '\n';
195 main(int argc, char * * argv)
197 static const struct diagnostic * diag = diagnostics;
200 EF_PROTECT_BELOW = 0;
201 EF_ALIGNMENT = 0;
203 while ( diag->explanation != 0 ) {
204 int status = gotSegmentationFault(diag->test);
206 if ( status != diag->expectedStatus ) {
208 * Don't use stdio to print here, because stdio
209 * uses malloc() and we've just proven that malloc()
210 * is broken. Also, use _exit() instead of exit(),
211 * because _exit() doesn't flush stdio.
213 write(2, failedTest, sizeof(failedTest) - 1);
214 write(2, diag->explanation, strlen(diag->explanation));
215 write(2, &newline, 1);
216 _exit(-1);
218 diag++;
220 return 0;