xref: /minix3/minix/tests/test5.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
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 int max_error = 3;
15 #include "common.h"
16 
17 
18 int subtest;
19 int zero[1024];
20 int sigmap[5] = {SIGKILL, SIGUSR1, SIGSEGV};
21 
22 
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);
41 
42 volatile int childsigs, parsigs, alarms;
43 
main(argc,argv)44 int main(argc, argv)
45 int argc;
46 char *argv[];
47 {
48   int i, m = 0x7777;
49 
50   start(5);
51 
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();
62   }
63   quit();
64   return(-1);			/* impossible */
65 }
66 
test5a()67 void test5a()
68 {
69   int parpid, childpid, flag, *zp;
70 
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);
84   }
85   if (signal(SIGHUP, SIG_DFL) == SIG_ERR) e(4);
86   if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) e(5);
87 }
88 
parent(childpid)89 void parent(childpid)
90 int childpid;
91 {
92   int i, pid;
93 
94   for (i = 0; i < 3; i++) {
95 	if (kill(childpid, SIGHUP) < 0) e(6);
96 	while (parsigs == 0);
97 	parsigs--;
98   }
99   if ( (pid = wait(&i)) < 0) e(7);
100   if (i != 256 * 6) e(8);
101 }
102 
child(parpid)103 void child(parpid)
104 int parpid;
105 {
106 
107   int i;
108 
109   for (i = 0; i < 3; i++) {
110 	while (childsigs == 0);
111 	childsigs--;
112 	if (kill(parpid, SIGUSR1) < 0) e(9);
113   }
114   exit(6);
115 }
116 
func1(s)117 void func1(s)
118 int s;				/* for ANSI */
119 {
120   if (signal(SIGHUP, func1) == SIG_ERR) e(10);
121   childsigs++;
122 }
123 
func8(s)124 void func8(s)
125 int s;
126 {
127 }
128 
func10(s)129 void func10(s)
130 int s;				/* for ANSI */
131 {
132   if (signal(SIGUSR1, func10) == SIG_ERR) e(11);
133   parsigs++;
134 }
135 
func11(s)136 void func11(s)
137 int s;				/* for ANSI */
138 {
139   e(38);
140 }
141 
test5b()142 void test5b()
143 {
144   int cpid, n, pid;
145 
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);
160 		}
161 	} else {
162 		exit(0);
163 	}
164   } else {
165 	exit(0);
166   }
167 }
168 
test5c()169 void test5c()
170 {
171   int n, i, pid, wpid;
172 
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);
182 		}
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);
189 	}
190   }
191 }
192 
test5d()193 void test5d()
194 {
195 /* Test alarm */
196 
197   int i;
198 
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);
206   }
207 }
208 
test5e()209 void test5e()
210 {
211 /* When a signal knocks a processes out of WAITPID or PAUSE, it is supposed to
212  * get EINTR as error status.  Check that.
213  */
214   int n;
215 
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);
229   }
230 }
231 
test5f()232 void test5f()
233 {
234   int i, j, k, n;
235 
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);
260   }
261 }
262 
test5g()263 void test5g()
264 {
265   int n;
266 
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);
273 }
274 
funcalrm(s)275 void funcalrm(s)
276 int s;				/* for ANSI */
277 {
278   alarms++;
279 }
280 
test5h()281 void test5h()
282 {
283 /* When a signal knocks a processes out of PIPE, it is supposed to
284  * get EINTR as error status.  Check that.
285  */
286   int n, fd[2];
287 
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);
308   }
309 }
310 
test5i()311 void test5i()
312 {
313   int fd[2], pid, buf[10], n;
314 
315   subtest = 9;
316   pipe(fd);
317   unlink("XXXxxxXXX");
318 
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 */
332   }
333   unlink("XXXxxxXXX");
334 }
335 
ex()336 void ex()
337 {
338   int e = errno;
339   printf("Fork failed: %s (%d)\n", strerror(e), e);
340   exit(1);
341 }
342 
343