- retrieve binary packages and sources from webserver to make a release, incremental...
[minix.git] / test / test5.c
blob28482081311e9e9049f669f377799215be12b44a
1 /* test 5 */
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>
13 #define ITERATIONS 2
14 #define MAX_ERROR 4
16 int errct;
17 int subtest;
18 int zero[1024];
20 int sigmap[5] = {9, 10, 11};
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));
43 #ifdef _ANSI
44 void (*Signal(int _sig, void (*_func)(int)))(int);
45 #define SIG_ZERO ((void (*)(int))0) /* default signal handling */
46 #else
47 sighandler_t Signal();
48 /* void (*Signal()) (); */
49 #define SIG_ZERO ((void (*)())0) /* default signal handling */
50 #endif
52 _VOLATILE int childsigs, parsigs, alarms;
54 int main(argc, argv)
55 int argc;
56 char *argv[];
58 int i, m = 0x7777;
60 printf("Test 5 ");
61 fflush(stdout); /* have to flush for child's benefit */
63 system("rm -rf DIR_05; mkdir DIR_05");
64 chdir("DIR_05");
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();
77 quit();
78 return(-1); /* impossible */
81 void test5a()
83 int parpid, childpid, flag, *zp;
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);
99 if (Signal(1, SIG_DFL) < SIG_ZERO) e(4);
100 if (Signal(10, SIG_DFL) < SIG_ZERO) e(5);
103 void parent(childpid)
104 int childpid;
106 int i, pid;
108 for (i = 0; i < 3; i++) {
109 if (kill(childpid, 1) < 0) e(6);
110 while (parsigs == 0);
111 parsigs--;
113 if ( (pid = wait(&i)) < 0) e(7);
114 if (i != 256 * 6) e(8);
117 void child(parpid)
118 int parpid;
121 int i;
123 for (i = 0; i < 3; i++) {
124 while (childsigs == 0);
125 childsigs--;
126 if (kill(parpid, 10) < 0) e(9);
128 exit(6);
131 void func1(s)
132 int s; /* for ANSI */
134 if (Signal(1, func1) < SIG_ZERO) e(10);
135 childsigs++;
138 void func8(s)
139 int s;
143 void func10(s)
144 int s; /* for ANSI */
146 if (Signal(10, func10) < SIG_ZERO) e(11);
147 parsigs++;
150 void func11(s)
151 int s; /* for ANSI */
153 e(38);
156 void test5b()
158 int cpid, n, pid;
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);
175 } else {
176 exit(0);
178 } else {
179 exit(0);
183 void test5c()
185 int n, i, pid, wpid;
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);
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);
207 void test5d()
209 /* Test alarm */
211 int i;
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);
223 void test5e()
225 /* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
226 * get EINTR as error status. Check that.
228 int n, j;
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);
246 void test5f()
248 int i, j, k, n;
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);
277 void test5g()
279 int n;
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);
289 void funcalrm(s)
290 int s; /* for ANSI */
292 alarms++;
295 void test5h()
297 /* When a signal knocks a processes out of PIPE, it is supposed to
298 * get EINTR as error status. Check that.
300 int n, j, fd[2];
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);
325 void test5i()
327 int fd[2], pid, buf[10], n;
329 subtest = 9;
330 pipe(fd);
331 unlink("XXXxxxXXX");
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 */
347 unlink("XXXxxxXXX");
350 void ex()
352 int e = errno;
353 printf("Fork failed: %s (%d)\n", strerror(e), e);
354 exit(1);
357 void e(n)
358 int n;
360 int err_num = errno; /* save errno in case printf clobbers it */
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);
373 #ifdef _ANSI
374 void (*Signal(int a, void (*b)(int)))(int)
375 #else
376 sighandler_t Signal(a, b)
377 int a;
378 void (*b)();
379 #endif
381 if (signal(a, (void (*) ()) b) == (void (*)()) -1)
382 return(SIG_ERR);
383 else
384 return(SIG_ZERO);
387 void quit()
390 chdir("..");
391 system("rm -rf DIR*");
393 if (errct == 0) {
394 printf("ok\n");
395 exit(0);
396 } else {
397 printf("%d errors\n", errct);
398 exit(1);