source: trunk/minix/test/test5.c@ 10

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

Minix 3.1.2a

File size: 7.2 KB
Line 
1/* test 5 */
2
3#include <sys/types.h>
4#include <sys/wait.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <signal.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <stdio.h>
11#include <string.h>
12
13#define ITERATIONS 2
14#define MAX_ERROR 4
15
16int errct;
17int subtest;
18int zero[1024];
19
20int sigmap[5] = {9, 10, 11};
21
22_PROTOTYPE(int main, (int argc, char *argv[]));
23_PROTOTYPE(void test5a, (void));
24_PROTOTYPE(void parent, (int childpid));
25_PROTOTYPE(void child, (int parpid));
26_PROTOTYPE(void func1, (int s));
27_PROTOTYPE(void func8, (int s));
28_PROTOTYPE(void func10, (int s));
29_PROTOTYPE(void func11, (int s));
30_PROTOTYPE(void test5b, (void));
31_PROTOTYPE(void test5c, (void));
32_PROTOTYPE(void test5d, (void));
33_PROTOTYPE(void test5e, (void));
34_PROTOTYPE(void test5f, (void));
35_PROTOTYPE(void test5g, (void));
36_PROTOTYPE(void funcalrm, (int s));
37_PROTOTYPE(void test5h, (void));
38_PROTOTYPE(void test5i, (void));
39_PROTOTYPE(void ex, (void));
40_PROTOTYPE(void e, (int n));
41_PROTOTYPE(void quit, (void));
42
43#ifdef _ANSI
44void (*Signal(int _sig, void (*_func)(int)))(int);
45#define SIG_ZERO ((void (*)(int))0) /* default signal handling */
46#else
47sighandler_t Signal();
48/* void (*Signal()) (); */
49#define SIG_ZERO ((void (*)())0) /* default signal handling */
50#endif
51
52_VOLATILE int childsigs, parsigs, alarms;
53
54int main(argc, argv)
55int argc;
56char *argv[];
57{
58 int i, m = 0x7777;
59
60 printf("Test 5 ");
61 fflush(stdout); /* have to flush for child's benefit */
62
63 system("rm -rf DIR_05; mkdir DIR_05");
64 chdir("DIR_05");
65
66 for (i = 0; i < ITERATIONS; i++) {
67 if (m & 0001) test5a();
68 if (m & 0002) test5b();
69 if (m & 0004) test5c();
70 if (m & 0010) test5d();
71 if (m & 0020) test5e();
72 if (m & 0040) test5f();
73 if (m & 0100) test5g();
74 if (m & 0200) test5h();
75 if (m & 0400) test5i();
76 }
77 quit();
78 return(-1); /* impossible */
79}
80
81void test5a()
82{
83 int parpid, childpid, flag, *zp;
84
85 subtest = 0;
86 flag = 0;
87 for (zp = &zero[0]; zp < &zero[1024]; zp++)
88 if (*zp != 0) flag = 1;
89 if (flag) e(0); /* check if bss is cleared to 0 */
90 if (Signal(1, func1) == SIG_ERR) e(1);
91 if (Signal(10, func10) < SIG_ZERO) e(2);
92 parpid = getpid();
93 if (childpid = fork()) {
94 if (childpid < 0) ex();
95 parent(childpid);
96 } else {
97 child(parpid);
98 }
99 if (Signal(1, SIG_DFL) < SIG_ZERO) e(4);
100 if (Signal(10, SIG_DFL) < SIG_ZERO) e(5);
101}
102
103void parent(childpid)
104int childpid;
105{
106 int i, pid;
107
108 for (i = 0; i < 3; i++) {
109 if (kill(childpid, 1) < 0) e(6);
110 while (parsigs == 0);
111 parsigs--;
112 }
113 if ( (pid = wait(&i)) < 0) e(7);
114 if (i != 256 * 6) e(8);
115}
116
117void child(parpid)
118int parpid;
119{
120
121 int i;
122
123 for (i = 0; i < 3; i++) {
124 while (childsigs == 0);
125 childsigs--;
126 if (kill(parpid, 10) < 0) e(9);
127 }
128 exit(6);
129}
130
131void func1(s)
132int s; /* for ANSI */
133{
134 if (Signal(1, func1) < SIG_ZERO) e(10);
135 childsigs++;
136}
137
138void func8(s)
139int s;
140{
141}
142
143void func10(s)
144int s; /* for ANSI */
145{
146 if (Signal(10, func10) < SIG_ZERO) e(11);
147 parsigs++;
148}
149
150void func11(s)
151int s; /* for ANSI */
152{
153 e(38);
154}
155
156void test5b()
157{
158 int cpid, n, pid;
159
160 subtest = 1;
161 if ((pid = fork())) {
162 if (pid < 0) ex();
163 if ((pid = fork())) {
164 if (pid < 0) ex();
165 if (cpid = fork()) {
166 if (cpid < 0) ex();
167 if (kill(cpid, 9) < 0) e(12);
168 if (wait(&n) < 0) e(13);
169 if (wait(&n) < 0) e(14);
170 if (wait(&n) < 0) e(15);
171 } else {
172 pause();
173 while (1);
174 }
175 } else {
176 exit(0);
177 }
178 } else {
179 exit(0);
180 }
181}
182
183void test5c()
184{
185 int n, i, pid, wpid;
186
187 /* Test exit status codes for processes killed by signals. */
188 subtest = 3;
189 for (i = 0; i < 2; i++) {
190 if (pid = fork()) {
191 if (pid < 0) ex();
192 sleep(2); /* wait for child to pause */
193 if (kill(pid, sigmap[i]) < 0) {
194 e(20);
195 exit(1);
196 }
197 if ((wpid = wait(&n)) < 0) e(21);
198 if ((n & 077) != sigmap[i]) e(22);
199 if (pid != wpid) e(23);
200 } else {
201 pause();
202 exit(0);
203 }
204 }
205}
206
207void test5d()
208{
209/* Test alarm */
210
211 int i;
212
213 subtest = 4;
214 alarms = 0;
215 for (i = 0; i < 8; i++) {
216 Signal(SIGALRM, funcalrm);
217 alarm(1);
218 pause();
219 if (alarms != i + 1) e(24);
220 }
221}
222
223void test5e()
224{
225/* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
226 * get EINTR as error status. Check that.
227 */
228 int n, j;
229
230 subtest = 5;
231 if (Signal(8, func8) < SIG_ZERO) e(25);
232 if (n = fork()) {
233 /* Parent must delay to give child a chance to pause. */
234 if (n < 0) ex();
235 sleep(1);
236 if (kill(n, 8) < 0) e(26);
237 if (wait(&n) < 0) e(27);
238 if (Signal(8, SIG_DFL) < SIG_ZERO) e(28);
239 } else {
240 j = pause();
241 if (errno != EINTR && -errno != EINTR) e(29);
242 exit(0);
243 }
244}
245
246void test5f()
247{
248 int i, j, k, n;
249
250 subtest = 6;
251 if (getuid() != 0) return;
252 n = fork();
253 if (n < 0) ex();
254 if (n) {
255 wait(&i);
256 i = (i >> 8) & 0377;
257 if (i != (n & 0377)) e(30);
258 } else {
259 i = getgid();
260 j = getegid();
261 k = (i + j + 7) & 0377;
262 if (setgid(k) < 0) e(31);
263 if (getgid() != k) e(32);
264 if (getegid() != k) e(33);
265 i = getuid();
266 j = geteuid();
267 k = (i + j + 1) & 0377;
268 if (setuid(k) < 0) e(34);
269 if (getuid() != k) e(35);
270 if (geteuid() != k) e(36);
271 i = getpid() & 0377;
272 if (wait(&j) != -1) e(37);
273 exit(i);
274 }
275}
276
277void test5g()
278{
279 int n;
280
281 subtest = 7;
282 Signal(11, func11);
283 Signal(11, SIG_IGN);
284 n = getpid();
285 if (kill(n, 11) != 0) e(1);
286 Signal(11, SIG_DFL);
287}
288
289void funcalrm(s)
290int s; /* for ANSI */
291{
292 alarms++;
293}
294
295void test5h()
296{
297/* When a signal knocks a processes out of PIPE, it is supposed to
298 * get EINTR as error status. Check that.
299 */
300 int n, j, fd[2];
301
302 subtest = 8;
303 unlink("XXX.test5");
304 if (Signal(8, func8) < SIG_ZERO) e(1);
305 pipe(fd);
306 if (n = fork()) {
307 /* Parent must delay to give child a chance to pause. */
308 if (n < 0) ex();
309 while (access("XXX.test5", 0) != 0) /* just wait */ ;
310 sleep(1);
311 unlink("XXX.test5");
312 if (kill(n, 8) < 0) e(2);
313 if (wait(&n) < 0) e(3);
314 if (Signal(8, SIG_DFL) < SIG_ZERO) e(4);
315 if (close(fd[0]) != 0) e(5);
316 if (close(fd[1]) != 0) e(6);
317 } else {
318 if (creat("XXX.test5", 0777) < 0) e(7);
319 j = read(fd[0], (char *) &n, 1);
320 if (errno != EINTR) e(8);
321 exit(0);
322 }
323}
324
325void test5i()
326{
327 int fd[2], pid, buf[10], n;
328
329 subtest = 9;
330 pipe(fd);
331 unlink("XXXxxxXXX");
332
333 if ( (pid = fork())) {
334 /* Parent */
335 /* Wait until child has started and has created the XXXxxxXXX file. */
336 while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
337 sleep(1);
338 if (kill(pid, SIGKILL) != 0) e(1);
339 if (wait(&n) < 0) e(2);
340 if (close(fd[0]) != 0) e(3);
341 if (close(fd[1]) != 0) e(4);
342 } else {
343 if (creat("XXXxxxXXX", 0777) < 0) e(5);
344 read(fd[0], (char *) buf, 1);
345 e(5); /* should be killed by signal and not get here */
346 }
347 unlink("XXXxxxXXX");
348}
349
350void ex()
351{
352 int e = errno;
353 printf("Fork failed: %s (%d)\n", strerror(e), e);
354 exit(1);
355}
356
357void e(n)
358int n;
359{
360 int err_num = errno; /* save errno in case printf clobbers it */
361
362 printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
363 errno = err_num; /* restore errno, just in case */
364 perror("");
365 if (errct++ > MAX_ERROR) {
366 printf("Too many errors; test aborted\n");
367 chdir("..");
368 system("rm -rf DIR*");
369 exit(1);
370 }
371}
372
373#ifdef _ANSI
374void (*Signal(int a, void (*b)(int)))(int)
375#else
376sighandler_t Signal(a, b)
377int a;
378void (*b)();
379#endif
380{
381 if (signal(a, (void (*) ()) b) == (void (*)()) -1)
382 return(SIG_ERR);
383 else
384 return(SIG_ZERO);
385}
386
387void quit()
388{
389
390 chdir("..");
391 system("rm -rf DIR*");
392
393 if (errct == 0) {
394 printf("ok\n");
395 exit(0);
396 } else {
397 printf("%d errors\n", errct);
398 exit(1);
399 }
400}
Note: See TracBrowser for help on using the repository browser.