source: trunk/minix/test/test9.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 4.3 KB
Line 
1/* Test 9 setjmp with register variables. Author: Ceriel Jacobs */
2
3#include <sys/types.h>
4#include <setjmp.h>
5#include <signal.h>
6
7#define MAX_ERROR 4
8
9#include "common.c"
10
11char *tmpa;
12
13_PROTOTYPE(int main, (int argc, char *argv []));
14_PROTOTYPE(void test9a, (void));
15_PROTOTYPE(void test9b, (void));
16_PROTOTYPE(void test9c, (void));
17_PROTOTYPE(void test9d, (void));
18_PROTOTYPE(void test9e, (void));
19_PROTOTYPE(void test9f, (void));
20_PROTOTYPE(char *addr, (void));
21_PROTOTYPE(void garbage, (void));
22_PROTOTYPE(void level1, (void));
23_PROTOTYPE(void level2, (void));
24_PROTOTYPE(void dolev, (void));
25_PROTOTYPE(void catch, (int s));
26_PROTOTYPE(void hard, (void));
27
28int main(argc, argv)
29int argc;
30char *argv[];
31{
32 jmp_buf envm;
33 int i, j, m = 0xFFFF;
34
35 start(9);
36 if (argc == 2) m = atoi(argv[1]);
37 for (j = 0; j < 100; j++) {
38 if (m & 00001) test9a();
39 if (m & 00002) test9b();
40 if (m & 00004) test9c();
41 if (m & 00010) test9d();
42 if (m & 00020) test9e();
43 if (m & 00040) test9f();
44 }
45 if (errct) quit();
46 i = 1;
47 if (setjmp(envm) == 0) {
48 i = 2;
49 longjmp(envm, 1);
50 } else {
51 if (i == 2) {
52 /* Correct */
53 } else if (i == 1) {
54 printf("WARNING: The setjmp/longjmp of this machine restore register variables\n\
55to the value they had at the time of the Setjmp\n");
56 } else {
57 printf("Aha, I just found one last error\n");
58 return 1;
59 }
60 }
61 quit();
62 return(-1); /* impossible */
63}
64
65void test9a()
66{
67 register p;
68
69 subtest = 1;
70 p = 200;
71 garbage();
72 if (p != 200) e(1);
73}
74
75void test9b()
76{
77 register p, q;
78
79 subtest = 2;
80 p = 200;
81 q = 300;
82 garbage();
83 if (p != 200) e(1);
84 if (q != 300) e(2);
85}
86
87void test9c()
88{
89 register p, q, r;
90
91 subtest = 3;
92 p = 200;
93 q = 300;
94 r = 400;
95 garbage();
96 if (p != 200) e(1);
97 if (q != 300) e(2);
98 if (r != 400) e(3);
99}
100
101char buf[512];
102
103void test9d()
104{
105 register char *p;
106
107 subtest = 4;
108 p = &buf[100];
109 garbage();
110 if (p != &buf[100]) e(1);
111}
112
113void test9e()
114{
115 register char *p, *q;
116
117 subtest = 5;
118 p = &buf[100];
119 q = &buf[200];
120 garbage();
121 if (p != &buf[100]) e(1);
122 if (q != &buf[200]) e(2);
123}
124
125void test9f()
126{
127 register char *p, *q, *r;
128
129 subtest = 6;
130 p = &buf[100];
131 q = &buf[200];
132 r = &buf[300];
133 garbage();
134 if (p != &buf[100]) e(1);
135 if (q != &buf[200]) e(2);
136 if (r != &buf[300]) e(3);
137}
138
139jmp_buf env;
140
141/* return address of local variable.
142 This way we can check that the stack is not polluted.
143*/
144char *
145 addr()
146{
147 char a;
148
149 return &a;
150}
151
152void garbage()
153{
154 register i, j, k;
155 register char *p, *q, *r;
156 char *a;
157
158 p = &buf[300];
159 q = &buf[400];
160 r = &buf[500];
161 i = 10;
162 j = 20;
163 k = 30;
164 switch (setjmp(env)) {
165 case 0:
166 a = addr();
167#ifdef __GNUC__
168 /*
169 * to defeat the smartness of the GNU C optimizer we pretend we
170 * use 'a'. Otherwise the optimizer will not detect the looping
171 * effectuated by setjmp/longjmp, so that it thinks it can get
172 * rid of the assignment to 'a'.
173 */
174 srand((unsigned)&a);
175#endif
176 longjmp(env, 1);
177 break;
178 case 1:
179 if (i != 10) e(11);
180 if (j != 20) e(12);
181 if (k != 30) e(13);
182 if (p != &buf[300]) e(14);
183 if (q != &buf[400]) e(15);
184 if (r != &buf[500]) e(16);
185 tmpa = addr();
186 if (a != tmpa) e(17);
187 level1();
188 break;
189 case 2:
190 if (i != 10) e(21);
191 if (j != 20) e(22);
192 if (k != 30) e(23);
193 if (p != &buf[300]) e(24);
194 if (q != &buf[400]) e(25);
195 if (r != &buf[500]) e(26);
196 tmpa = addr();
197 if (a != tmpa) e(27);
198 level2();
199 break;
200 case 3:
201 if (i != 10) e(31);
202 if (j != 20) e(32);
203 if (k != 30) e(33);
204 if (p != &buf[300]) e(34);
205 if (q != &buf[400]) e(35);
206 if (r != &buf[500]) e(36);
207 tmpa = addr();
208 if (a != tmpa) e(37);
209 hard();
210 case 4:
211 if (i != 10) e(41);
212 if (j != 20) e(42);
213 if (k != 30) e(43);
214 if (p != &buf[300]) e(44);
215 if (q != &buf[400]) e(45);
216 if (r != &buf[500]) e(46);
217 tmpa = addr();
218 if (a != tmpa) e(47);
219 return;
220 break;
221 default: e(100);
222 }
223 e(200);
224}
225
226void level1()
227{
228 register char *p;
229 register i;
230
231 i = 1000;
232 p = &buf[10];
233 i = 200;
234 p = &buf[20];
235 longjmp(env, 2);
236}
237
238void level2()
239{
240 register char *p;
241 register i;
242
243 i = 0200;
244 p = &buf[2];
245 *p = i;
246 dolev();
247}
248
249void dolev()
250{
251 register char *p;
252 register i;
253
254 i = 010;
255 p = &buf[3];
256 *p = i;
257 longjmp(env, 3);
258}
259
260void catch(s)
261int s;
262{
263 longjmp(env, 4);
264}
265
266void hard()
267{
268 register char *p;
269
270 signal(SIGHUP, catch);
271 for (p = buf; p <= &buf[511]; p++) *p = 025;
272 kill(getpid(), SIGHUP);
273}
Note: See TracBrowser for help on using the repository browser.