Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / tests / test5.c
blob7650ee6db12102d1c654f71086b3f7e43217f1c2
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 int max_error = 3;
15 #include "common.h"
18 int subtest;
19 int zero[1024];
20 int sigmap[5] = {SIGKILL, SIGUSR1, SIGSEGV};
23 int main(int argc, char *argv[]);
24 void test5a(void);
25 void parent(int childpid);
26 void child(int parpid);
27 void func1(int s);
28 void func8(int s);
29 void func10(int s);
30 void func11(int s);
31 void test5b(void);
32 void test5c(void);
33 void test5d(void);
34 void test5e(void);
35 void test5f(void);
36 void test5g(void);
37 void funcalrm(int s);
38 void test5h(void);
39 void test5i(void);
40 void ex(void);
42 volatile int childsigs, parsigs, alarms;
44 int main(argc, argv)
45 int argc;
46 char *argv[];
48 int i, m = 0x7777;
50 start(5);
52 for (i = 0; i < ITERATIONS; i++) {
53 if (m & 0001) test5a();
54 if (m & 0002) test5b();
55 if (m & 0004) test5c();
56 if (m & 0010) test5d();
57 if (m & 0020) test5e();
58 if (m & 0040) test5f();
59 if (m & 0100) test5g();
60 if (m & 0200) test5h();
61 if (m & 0400) test5i();
63 quit();
64 return(-1); /* impossible */
67 void test5a()
69 int parpid, childpid, flag, *zp;
71 subtest = 0;
72 flag = 0;
73 for (zp = &zero[0]; zp < &zero[1024]; zp++)
74 if (*zp != 0) flag = 1;
75 if (flag) e(0); /* check if bss is cleared to 0 */
76 if (signal(SIGHUP, func1) == SIG_ERR) e(1);
77 if (signal(SIGUSR1, func10) == SIG_ERR) e(2);
78 parpid = getpid();
79 if ((childpid = fork()) != 0) {
80 if (childpid < 0) ex();
81 parent(childpid);
82 } else {
83 child(parpid);
85 if (signal(SIGHUP, SIG_DFL) == SIG_ERR) e(4);
86 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) e(5);
89 void parent(childpid)
90 int childpid;
92 int i, pid;
94 for (i = 0; i < 3; i++) {
95 if (kill(childpid, SIGHUP) < 0) e(6);
96 while (parsigs == 0);
97 parsigs--;
99 if ( (pid = wait(&i)) < 0) e(7);
100 if (i != 256 * 6) e(8);
103 void child(parpid)
104 int parpid;
107 int i;
109 for (i = 0; i < 3; i++) {
110 while (childsigs == 0);
111 childsigs--;
112 if (kill(parpid, SIGUSR1) < 0) e(9);
114 exit(6);
117 void func1(s)
118 int s; /* for ANSI */
120 if (signal(SIGHUP, func1) == SIG_ERR) e(10);
121 childsigs++;
124 void func8(s)
125 int s;
129 void func10(s)
130 int s; /* for ANSI */
132 if (signal(SIGUSR1, func10) == SIG_ERR) e(11);
133 parsigs++;
136 void func11(s)
137 int s; /* for ANSI */
139 e(38);
142 void test5b()
144 int cpid, n, pid;
146 subtest = 1;
147 if ((pid = fork()) != 0) {
148 if (pid < 0) ex();
149 if ((pid = fork()) != 0) {
150 if (pid < 0) ex();
151 if ((cpid = fork()) != 0) {
152 if (cpid < 0) ex();
153 if (kill(cpid, SIGKILL) < 0) e(12);
154 if (wait(&n) < 0) e(13);
155 if (wait(&n) < 0) e(14);
156 if (wait(&n) < 0) e(15);
157 } else {
158 pause();
159 while (1);
161 } else {
162 exit(0);
164 } else {
165 exit(0);
169 void test5c()
171 int n, i, pid, wpid;
173 /* Test exit status codes for processes killed by signals. */
174 subtest = 3;
175 for (i = 0; i < 2; i++) {
176 if ((pid = fork()) != 0) {
177 if (pid < 0) ex();
178 sleep(2); /* wait for child to pause */
179 if (kill(pid, sigmap[i]) < 0) {
180 e(20);
181 exit(1);
183 if ((wpid = wait(&n)) < 0) e(21);
184 if ((n & 077) != sigmap[i]) e(22);
185 if (pid != wpid) e(23);
186 } else {
187 pause();
188 exit(0);
193 void test5d()
195 /* Test alarm */
197 int i;
199 subtest = 4;
200 alarms = 0;
201 for (i = 0; i < 8; i++) {
202 signal(SIGALRM, funcalrm);
203 alarm(1);
204 pause();
205 if (alarms != i + 1) e(24);
209 void test5e()
211 /* When a signal knocks a processes out of WAITPID or PAUSE, it is supposed to
212 * get EINTR as error status. Check that.
214 int n;
216 subtest = 5;
217 if (signal(SIGFPE, func8) == SIG_ERR) e(25);
218 if ((n = fork()) != 0) {
219 /* Parent must delay to give child a chance to pause. */
220 if (n < 0) ex();
221 sleep(1);
222 if (kill(n, SIGFPE) < 0) e(26);
223 if (wait(&n) < 0) e(27);
224 if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(28);
225 } else {
226 (void) pause();
227 if (errno != EINTR && -errno != EINTR) e(29);
228 exit(0);
232 void test5f()
234 int i, j, k, n;
236 subtest = 6;
237 if (getuid() != 0) return;
238 n = fork();
239 if (n < 0) ex();
240 if (n) {
241 wait(&i);
242 i = (i >> 8) & 0377;
243 if (i != (n & 0377)) e(30);
244 } else {
245 i = getgid();
246 j = getegid();
247 k = (i + j + 7) & 0377;
248 if (setgid(k) < 0) e(31);
249 if (getgid() != k) e(32);
250 if (getegid() != k) e(33);
251 i = getuid();
252 j = geteuid();
253 k = (i + j + 1) & 0377;
254 if (setuid(k) < 0) e(34);
255 if (getuid() != k) e(35);
256 if (geteuid() != k) e(36);
257 i = getpid() & 0377;
258 if (wait(&j) != -1) e(37);
259 exit(i);
263 void test5g()
265 int n;
267 subtest = 7;
268 signal(SIGSEGV, func11);
269 signal(SIGSEGV, SIG_IGN);
270 n = getpid();
271 if (kill(n, SIGSEGV) != 0) e(1);
272 signal(SIGSEGV, SIG_DFL);
275 void funcalrm(s)
276 int s; /* for ANSI */
278 alarms++;
281 void test5h()
283 /* When a signal knocks a processes out of PIPE, it is supposed to
284 * get EINTR as error status. Check that.
286 int n, fd[2];
288 subtest = 8;
289 unlink("XXX.test5");
290 if (signal(SIGFPE, func8) == SIG_ERR) e(1);
291 pipe(fd);
292 if ((n = fork()) != 0) {
293 /* Parent must delay to give child a chance to pause. */
294 if (n < 0) ex();
295 while (access("XXX.test5", 0) != 0) /* just wait */ ;
296 sleep(1);
297 unlink("XXX.test5");
298 if (kill(n, SIGFPE) < 0) e(2);
299 if (wait(&n) < 0) e(3);
300 if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(4);
301 if (close(fd[0]) != 0) e(5);
302 if (close(fd[1]) != 0) e(6);
303 } else {
304 if (creat("XXX.test5", 0777) < 0) e(7);
305 (void) read(fd[0], (char *) &n, 1);
306 if (errno != EINTR) e(8);
307 exit(0);
311 void test5i()
313 int fd[2], pid, buf[10], n;
315 subtest = 9;
316 pipe(fd);
317 unlink("XXXxxxXXX");
319 if ((pid = fork()) != 0) {
320 /* Parent */
321 /* Wait until child has started and has created the XXXxxxXXX file. */
322 while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
323 sleep(1);
324 if (kill(pid, SIGKILL) != 0) e(1);
325 if (wait(&n) < 0) e(2);
326 if (close(fd[0]) != 0) e(3);
327 if (close(fd[1]) != 0) e(4);
328 } else {
329 if (creat("XXXxxxXXX", 0777) < 0) e(5);
330 read(fd[0], (char *) buf, 1);
331 e(5); /* should be killed by signal and not get here */
333 unlink("XXXxxxXXX");
336 void ex()
338 int e = errno;
339 printf("Fork failed: %s (%d)\n", strerror(e), e);
340 exit(1);