tests: print error locations verbosely
[minix.git] / test / test5.c
blob2960d8f27284e4e6fa666d8c54f0381ed5218d14
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 3
16 int subtest;
17 int zero[1024];
18 int sigmap[5] = {9, 10, 11};
20 #include "common.c"
22 int main(int argc, char *argv[]);
23 void test5a(void);
24 void parent(int childpid);
25 void child(int parpid);
26 void func1(int s);
27 void func8(int s);
28 void func10(int s);
29 void func11(int s);
30 void test5b(void);
31 void test5c(void);
32 void test5d(void);
33 void test5e(void);
34 void test5f(void);
35 void test5g(void);
36 void funcalrm(int s);
37 void test5h(void);
38 void test5i(void);
39 void ex(void);
41 volatile int childsigs, parsigs, alarms;
43 int main(argc, argv)
44 int argc;
45 char *argv[];
47 int i, m = 0x7777;
49 start(5);
51 for (i = 0; i < ITERATIONS; i++) {
52 if (m & 0001) test5a();
53 if (m & 0002) test5b();
54 if (m & 0004) test5c();
55 if (m & 0010) test5d();
56 if (m & 0020) test5e();
57 if (m & 0040) test5f();
58 if (m & 0100) test5g();
59 if (m & 0200) test5h();
60 if (m & 0400) test5i();
62 quit();
63 return(-1); /* impossible */
66 void test5a()
68 int parpid, childpid, flag, *zp;
70 subtest = 0;
71 flag = 0;
72 for (zp = &zero[0]; zp < &zero[1024]; zp++)
73 if (*zp != 0) flag = 1;
74 if (flag) e(0); /* check if bss is cleared to 0 */
75 if (signal(1, func1) == SIG_ERR) e(1);
76 if (signal(10, func10) == SIG_ERR) e(2);
77 parpid = getpid();
78 if ((childpid = fork()) != 0) {
79 if (childpid < 0) ex();
80 parent(childpid);
81 } else {
82 child(parpid);
84 if (signal(1, SIG_DFL) == SIG_ERR) e(4);
85 if (signal(10, SIG_DFL) == SIG_ERR) e(5);
88 void parent(childpid)
89 int childpid;
91 int i, pid;
93 for (i = 0; i < 3; i++) {
94 if (kill(childpid, 1) < 0) e(6);
95 while (parsigs == 0);
96 parsigs--;
98 if ( (pid = wait(&i)) < 0) e(7);
99 if (i != 256 * 6) e(8);
102 void child(parpid)
103 int parpid;
106 int i;
108 for (i = 0; i < 3; i++) {
109 while (childsigs == 0);
110 childsigs--;
111 if (kill(parpid, 10) < 0) e(9);
113 exit(6);
116 void func1(s)
117 int s; /* for ANSI */
119 if (signal(1, func1) == SIG_ERR) e(10);
120 childsigs++;
123 void func8(s)
124 int s;
128 void func10(s)
129 int s; /* for ANSI */
131 if (signal(10, func10) == SIG_ERR) e(11);
132 parsigs++;
135 void func11(s)
136 int s; /* for ANSI */
138 e(38);
141 void test5b()
143 int cpid, n, pid;
145 subtest = 1;
146 if ((pid = fork()) != 0) {
147 if (pid < 0) ex();
148 if ((pid = fork()) != 0) {
149 if (pid < 0) ex();
150 if ((cpid = fork()) != 0) {
151 if (cpid < 0) ex();
152 if (kill(cpid, 9) < 0) e(12);
153 if (wait(&n) < 0) e(13);
154 if (wait(&n) < 0) e(14);
155 if (wait(&n) < 0) e(15);
156 } else {
157 pause();
158 while (1);
160 } else {
161 exit(0);
163 } else {
164 exit(0);
168 void test5c()
170 int n, i, pid, wpid;
172 /* Test exit status codes for processes killed by signals. */
173 subtest = 3;
174 for (i = 0; i < 2; i++) {
175 if ((pid = fork()) != 0) {
176 if (pid < 0) ex();
177 sleep(2); /* wait for child to pause */
178 if (kill(pid, sigmap[i]) < 0) {
179 e(20);
180 exit(1);
182 if ((wpid = wait(&n)) < 0) e(21);
183 if ((n & 077) != sigmap[i]) e(22);
184 if (pid != wpid) e(23);
185 } else {
186 pause();
187 exit(0);
192 void test5d()
194 /* Test alarm */
196 int i;
198 subtest = 4;
199 alarms = 0;
200 for (i = 0; i < 8; i++) {
201 signal(SIGALRM, funcalrm);
202 alarm(1);
203 pause();
204 if (alarms != i + 1) e(24);
208 void test5e()
210 /* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
211 * get EINTR as error status. Check that.
213 int n;
215 subtest = 5;
216 if (signal(8, func8) == SIG_ERR) e(25);
217 if ((n = fork()) != 0) {
218 /* Parent must delay to give child a chance to pause. */
219 if (n < 0) ex();
220 sleep(1);
221 if (kill(n, 8) < 0) e(26);
222 if (wait(&n) < 0) e(27);
223 if (signal(8, SIG_DFL) == SIG_ERR) e(28);
224 } else {
225 (void) pause();
226 if (errno != EINTR && -errno != EINTR) e(29);
227 exit(0);
231 void test5f()
233 int i, j, k, n;
235 subtest = 6;
236 if (getuid() != 0) return;
237 n = fork();
238 if (n < 0) ex();
239 if (n) {
240 wait(&i);
241 i = (i >> 8) & 0377;
242 if (i != (n & 0377)) e(30);
243 } else {
244 i = getgid();
245 j = getegid();
246 k = (i + j + 7) & 0377;
247 if (setgid(k) < 0) e(31);
248 if (getgid() != k) e(32);
249 if (getegid() != k) e(33);
250 i = getuid();
251 j = geteuid();
252 k = (i + j + 1) & 0377;
253 if (setuid(k) < 0) e(34);
254 if (getuid() != k) e(35);
255 if (geteuid() != k) e(36);
256 i = getpid() & 0377;
257 if (wait(&j) != -1) e(37);
258 exit(i);
262 void test5g()
264 int n;
266 subtest = 7;
267 signal(11, func11);
268 signal(11, SIG_IGN);
269 n = getpid();
270 if (kill(n, 11) != 0) e(1);
271 signal(11, SIG_DFL);
274 void funcalrm(s)
275 int s; /* for ANSI */
277 alarms++;
280 void test5h()
282 /* When a signal knocks a processes out of PIPE, it is supposed to
283 * get EINTR as error status. Check that.
285 int n, fd[2];
287 subtest = 8;
288 unlink("XXX.test5");
289 if (signal(8, func8) == SIG_ERR) e(1);
290 pipe(fd);
291 if ((n = fork()) != 0) {
292 /* Parent must delay to give child a chance to pause. */
293 if (n < 0) ex();
294 while (access("XXX.test5", 0) != 0) /* just wait */ ;
295 sleep(1);
296 unlink("XXX.test5");
297 if (kill(n, 8) < 0) e(2);
298 if (wait(&n) < 0) e(3);
299 if (signal(8, SIG_DFL) == SIG_ERR) e(4);
300 if (close(fd[0]) != 0) e(5);
301 if (close(fd[1]) != 0) e(6);
302 } else {
303 if (creat("XXX.test5", 0777) < 0) e(7);
304 (void) read(fd[0], (char *) &n, 1);
305 if (errno != EINTR) e(8);
306 exit(0);
310 void test5i()
312 int fd[2], pid, buf[10], n;
314 subtest = 9;
315 pipe(fd);
316 unlink("XXXxxxXXX");
318 if ((pid = fork()) != 0) {
319 /* Parent */
320 /* Wait until child has started and has created the XXXxxxXXX file. */
321 while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
322 sleep(1);
323 if (kill(pid, SIGKILL) != 0) e(1);
324 if (wait(&n) < 0) e(2);
325 if (close(fd[0]) != 0) e(3);
326 if (close(fd[1]) != 0) e(4);
327 } else {
328 if (creat("XXXxxxXXX", 0777) < 0) e(5);
329 read(fd[0], (char *) buf, 1);
330 e(5); /* should be killed by signal and not get here */
332 unlink("XXXxxxXXX");
335 void ex()
337 int e = errno;
338 printf("Fork failed: %s (%d)\n", strerror(e), e);
339 exit(1);